前言
我們正在實現一個需要通過https使用外部API的API(恐怕我們不能使用WCF或者甚至是舊式SOAP WebServices)的MVC2站點。無論我們需要與API進行通信,我們都在使用AsyncController
,到目前爲止一切正常。ASP.NET MVC2 AsyncController:在系列中執行多個異步操作是否會導致競爭狀況?
在我們需要進行多個API調用的情況下,我們需要使用一些場景,使用一步執行的結果來執行下一個調用。
一般模式(簡體用於演示目的)到目前爲止如下:
public class WhateverController : AsyncController
{
public void DoStuffAsync(DoStuffModel data)
{
AsyncManager.OutstandingOperations.Increment();
var apiUri = API.getCorrectServiceUri();
var req = new WebClient();
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["result"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
req.DownloadStringAsync(apiUri);
}
public ActionResult DoStuffCompleted(string result)
{
return View(result);
}
}
我們有幾個操作需要進行並行工作就好已經API調用;我們只是執行多個請求,並確保我們正確地增加AsyncManager.OutstandingOperations
。
場景
要進行串聯的多個API的服務請求,我們目前正在呼籲在第一次請求的DownloadStringCompleted
事件處理程序中的下一個步驟。例如,
req.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["step1"] = e.Result;
OtherActionAsync(e.Result);
AsyncManager.OutstandingOperations.Decrement();
}
其中OtherActionAsync
是按照相同的圖案如上述定義在本同一個控制器中定義的另一個動作。
問題
可調用從事件處理程序內的其他異步操作中AsyncManager
訪問值時,導致可能的比賽?
我試着環顧MSDN,但所有關於AsyncManager.Sync()
的評論都是關於BeginGethod/EndMethod模式和IAsyncCallback
。在這種情況下,文件警告潛在的競爭條件。
我們並不需要實際調用控制器內的其他操作,如果這對您不利。構建另一個WebClient
並致電.DownloadStringAsync()
的代碼可以很容易地放置在第一個請求的事件處理程序中。我剛纔已經在這裏展示了它,讓它更容易閱讀。
希望這是有道理的!如果沒有,請留下評論,我會嘗試澄清你喜歡的任何內容。
謝謝!
是OtherActionAsync(e.Result)甚至將要在這個例子中異步調用? WebClient完成下載字符串時不會同步調用它嗎? – JimmyP
它將包含對.DownloadStringAsync()的另一個調用,它將擁有自己的DownloadStringCompleted事件處理程序。 – rejj
嗯好吧,我仍然很難看到你的比賽狀況是對不起。只要OutstandingOperations正確地遞增和遞減,那麼所有的值都應該在DoStuffCompleted中可用 – JimmyP