asp.net mvc async等待主线程没有阻塞

时间:2016-05-23 10:28:40

标签: c# asp.net-mvc async-await task-parallel-library

  public async Task<ActionResult> Search(string q)
  {    
       var data = db.MediaPlanBilingInvoices.Where(m => m.IsDeleted == false);
            //allthe stuff        


            decimal? allinvoicetotal=0;
            decimal? allrototal = 0;
            if (Noofrecords > 0)
            {                
                    if (WebConstants.PrintMedia)
                    {
                       var roobject = data.Where(x => x.isPrint == true).SelectMany(m => m.MediaPlanBilingInvoiceDetails);
                       var roobjects =roobject.Select(m=>m.RoId);

                       Func<decimal?> functions = new Func<decimal?>(() => roobject.Sum(m => m.MediaPlanRO.MediaPlanROPrints.Sum(qq => qq.MediaPlanPrint.Amount)));
                       var tasksro = await System.Threading.Tasks.Task.Factory.StartNew<decimal?>(functions);    


                       allrototal = allrototal + tasksro.Result;

                }
                else if (WebConstants.ElectronicMedia)
                {
                    var roobject = data.Where(x => x.iselectronic == true).SelectMany(m => m.MediaPlanBilingInvoiceDetails);
                    var roobjects =roobject.Select(m=>m.RoId);

                    Func<decimal?> functions = new Func<decimal?>(() => roobject.Sum(m => m.MediaPlanRO.MediaPlanROPrints.Sum(qq => qq.MediaPlanPrint.Amount)));
                    var tasksro = await System.Threading.Tasks.Task.Factory.StartNew<decimal?>functions);   


                   allrototal = allrototal + tasksro ;
                }
              }                   
          }

                return Viewdata);
            }
        }

我正在尝试根据不同的标准计算不同表格中ros的总和。

问题是,当程序重新启动 allrototal 时,它会停止并且不会转到下一行,直到它关闭结果。我想让它继续运行并不止于此。我该怎么做?

1 个答案:

答案 0 :(得分:4)

您遇到的核心问题是async doesn't change the HTTP protocol(我的博客详细讨论过)。使用HTTP,您有一个请求和一个响应。如果你返回一个响应,那么你还有其他东西正在运行,然后再返回另一个响应 - HTTP就是不能那样工作。

因此,在ASP.NET上,async允许您释放线程,但完成响应。在async方法完成之前,不会发送响应。

此外,Task.Run is safer than StartNew,但都不应该像这样在ASP.NET上使用,因为它所做的只是通过使用另一个线程池线程来释放请求线程池线程。所以await Task.Run(() => functions());只是说functions()的一种更昂贵的方式。

这个方法应该是同步的。这里没有异步工作要做。如果您希望客户端以异步方式运行,那么客户端将需要异步发出HTTP请求。