ASP.NET MVC2 AsyncController:在系列中执行多个异步操作是否会导致竞争状况?
前言
我们正在实现一个需要通过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