ASP.NET MVC2 AsyncController:串行执行多个异步操作会导致可能的竞争条件吗?

时间:2011-09-07 02:48:44

标签: asp.net-mvc-2 asynchronous race-condition

序言

我们正在实现一个需要通过https使用外部API的MVC2站点(我们不能使用WCF甚至是老式的SOAP Web服务,我担心)。我们在需要与API通信的地方使用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()的所有评论都与IAsyncCallback的BeginMethod / EndMethod模式有关。在那种情况下,文档会警告潜在的竞争条件。

我们不需要在控制器内实际调用另一个动作,如果这对你不利。构建另一个WebClient并在其上调用.DownloadStringAsync()的代码可以很容易地放在第一个请求的事件处理程序中。我刚刚在这里展示了它,使其更容易阅读。

希望这是有道理的!如果没有,请发表评论,我会尝试澄清你喜欢的任何内容。

谢谢!

1 个答案:

答案 0 :(得分:0)

事实证明答案是“不”。

(以供将来参考,任何人都可以通过搜索遇到这个问题)