Async不适用于大型ASP.NET应用程序,但适用于新应用程序

时间:2015-10-21 05:42:31

标签: c# asp.net asp.net-mvc asynchronous async-await

我有一个现有的大型ASP.NET(ASP.NET Web Forms + MVC支持)应用程序,并尝试在项目上实现async编程。

为此我选择了ASP.NET应用程序(再次是ASP.NET Web Forms + MVC支持),创建了一个全新的POC。我的POC运行良好且正确执行async

现在,当我在现有大型项目中复制完全相同的代码时,其行为类似于synchronous。我已经在大型应用程序中拥有最新的.NET Framework更新。 这是我的Controller实现,它应该上传文件async

[HttpPost]
[ValidateInput(false)]
public async Task<JsonResult> VideoUpload(string Id)
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        // :::::
        await Run(fileStream);
    }

    return Json(new { error = false, message = "File uploaded." });
}

public async Task Run(Stream fileStream)
{
    // :::::

    using (fileStream)
    {
        // A long running method call
        await fileUploadRequest.UploadAsync();
    }
}

[HttpGet]
public JsonResult GetUploadingStatus()
{
    // :::::
    return Json(new { statusMessage = statusMessage, totalSent = totalSent, totalSize = totalSize }, JsonRequestBehavior.AllowGet);
}

在上面的代码GetUploadingStatus()中,GET方法可以快速完成工作。此方法接收随机(3-4秒间隔)Ajax调用并返回上载状态。

当我在大型项目中调试此实现时,我注意到GetUploadingStatus()fileUploadRequest.UploadAsync()结束后立即返回每个结果(10-15 Json响应)。所以我觉得这在大型项目中表现得像synchronous。那么为什么这个项目在一个干净的项目中很有效,但在大型项目中呢?

3 个答案:

答案 0 :(得分:1)

我的理解是您正在进行并行请求:1请求是在您向GetUploadingStatus请求上传进度的同时上传文件。

在这种情况下,ASP.NET会话状态的工作方式,可能会导致您提到的行为。正如本回答中提到的Why would multiple simultaneous AJAX calls to the same ASP.NET MVC action cause the browser to block?第二个请求仅在执行第一个请求后执行。正如你所提到的那样,它正如你所提到的那样...... GetUploadingStatus()在fileUploadRequest.UploadAsync()结束后一次返回每个结果(10-15 Json响应)。&#34;

除了亚历克斯提到的那样,你错误地混合了#as; async progrming&#34;使用&#34;并行编程&#34;即在这种情况下的并行请求..

答案 1 :(得分:1)

  

那么为什么这在干净的项目中很有效,但在大型项目中却不行?

async / await仅在.NET 4.5上运行时才能正常工作。

要升级旧的ASP.NET项目,您必须执行两个步骤:

  1. 将目标框架更改为.NET 4.5(或更新版本)。
  2. httpRuntime.targetFramework setting in your web.config更改为“4.5”(或更新版本)。
  3. 将现有ASP.NET项目升级到最新版本的.NET时,Visual Studio将执行上述第一步,您必须手动执行第二步。但是,如果在最新版本的.NET上创建新的ASP.NET项目,Visual Studio将执行这两个步骤。

答案 2 :(得分:0)

要解决此问题,我刚刚在控制器中添加了[SessionState(SessionStateBehavior.Disabled)],您可以在下面看到:

[SessionState(SessionStateBehavior.Disabled)]
public class UploadController : Controller
{
    [HttpPost]
    [ValidateInput(false)]
    public async Task<JsonResult> VideoUpload(string Id)
    {
        for (int i = 0; i < Request.Files.Count; i++)
        {
            // :::::
            await Run(fileStream);
        }

        return Json(new { error = false, message = "File uploaded." });
    }

    public async Task Run(Stream fileStream)
    {
        // :::::

        using (fileStream)
        {
            // A long running method call
            await fileUploadRequest.UploadAsync();
        }
    }

    [HttpGet]
    public JsonResult GetUploadingStatus()
    {
        // :::::
        return Json(new { statusMessage = statusMessage, totalSent = totalSent, totalSize = totalSize }, JsonRequestBehavior.AllowGet);
    }
}

使用此注释可能会打开一些安全漏洞,因此请在注释控制器之前自行验证。

希望你觉得这很有用。