繁体   English   中英

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

[英]Async is not working in large ASP.NET Application but in new application

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

为此,我通过选择ASP.NET应用程序(同样是ASP.NET Web窗体+ 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()结束后, GetUploadingStatus()一次返回每个结果(10-15 Json响应)。 所以我觉得这在大型项目中表现得像synchronous 那么,为什么这在干净的项目中效果很好,但在大型项目中效果不佳?

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

在这种情况下,ASP.NET会话状态的工作方式可能导致您提到的行为。 如本答案所述, 为什么对同一个ASP.NET MVC操作同时进行多个AJAX调用会导致浏览器阻塞? 第二个请求仅在第一个请求执行后执行。 就像您提到的“ ..GetUploadingStatus()在fileUploadRequest.UploadAsync()结束之后,一次返回每个结果(10-15 Json响应)一样。”

除了Alex提到的以外,您在这种情况下还错误地将“异步编程”与“并行编程”(即并行请求)混合使用。

那么,为什么这在干净的项目中效果很好,但在大型项目中效果不佳?

仅当在.NET 4.5上运行时, async / await才可以正常工作。

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

  1. 将目标框架更改为.NET 4.5(或更高版本)。
  2. 将您的web.confighttpRuntime.targetFramework设置更改为“ 4.5”(或更高版本)。

当您将现有的ASP.NET项目升级到最新版本的.NET时,Visual Studio将执行上述第一步,而您必须手动执行第二步。 但是,如果您在最新版本的.NET上创建一个新的ASP.NET项目,Visual Studio将完成这两个步骤。

要解决此问题,我刚刚添加了[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);
    }
}

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

希望您觉得这个有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM