Async在大型ASP中不起作用.NET应用程序,但在新的应用程序

本文关键字:应用程序 不起作用 大型 ASP Async NET | 更新日期: 2023-09-27 18:18:33

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

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

现在,当我复制完全相同的代码在现有的大型项目,这行为像synchronous。我已经在大型应用程序中更新了最新的。net框架。这是我的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方法做快速工作。该方法随机接收Ajax调用(间隔3-4秒),并返回上传状态。

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

Async在大型ASP中不起作用.NET应用程序,但在新的应用程序

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

在这种情况下,ASP。. NET会话状态工作,它可能导致您提到的行为。正如本文中所提到的,为什么对同一个ASP的多个同时AJAX调用?. NET MVC动作导致浏览器阻塞?第二个请求只在第一个请求执行之后执行。它是一样的,你正在经历,因为你提到"..GetUploadingStatus()返回每一个结果(10-15 Json响应)在一次之后,fileUploadRequest.UploadAsync()结束.."

除此之外,正如Alex提到的,你错误地将"异步编程"与"并行编程"混合在一起,即在这种情况下并行请求。

那么为什么这在一个干净的项目中工作得很好,而不是在大型项目中?

async/await只在。net 4.5上正常运行。

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

  1. 将目标框架改为。net 4.5(或更新版本)。
  2. web.config中的httpRuntime.targetFramework设置更改为"4.5"(或更新)。

当您升级现有的ASP。.NET项目到。NET的最新版本,Visual Studio将只执行上面的第一步,而您必须手动执行第二步。但是,如果创建一个新的ASP。.NET项目在最新版本的。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);
    }
}

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