【问题标题】:asp.net mvc async await making main thread not blockingasp.net mvc async await 使主线程不阻塞
【发布时间】:2016-05-23 19:46:13
【问题描述】:
  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 的总和。

问题在于,当程序到达 allrottotal 时,它会停止并且不会转到下一行,直到它降低结果为止。我想让它继续运行而不是停在那里。我该怎么做?

【问题讨论】:

  • 这就是 async/await 的作用。它使线程非阻塞,以便其他请求可以使用它。
  • 这就是 async/await 的工作原理,在结果可用之前你不能使用它。
  • 一旦 pgogram 找到 startnew 就会开始在后台执行查询?
  • @maz3tt 要记住的重要一点:异步不一定会减少加载时间(尤其是在无法执行并行任务的情况下),但它优化了线程的使用(即它允许线程用于其他事情在长期运行期间)。
  • 你读过StartNew is Dangerous的文章了吗?

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


【解决方案1】:

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

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

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

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

【讨论】:

  • 您有大量关于异步的文章。那么,如果我将上述 50 秒查询分解为 5 个 10 秒查询,您有何看法。多线程?
  • 10 秒查询并行运行
  • @maz3tt:这很危险,IMO。您当然可以尝试,但您需要在实际负载条件下进行测试。 ASP.NET 上的并行性通常在生产环境中效果不佳,除非您知道您的请求数量总是很低。每个达到此问题的请求将占用 5 个线程而不是 1 个,并且线程是请求中最重的资源之一,因此您的服务器的可扩展性将受到很大限制。
  • 好的,我现在可以看到它在哪里,所以我不会尝试,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 2012-06-11
  • 2023-03-24
  • 2018-05-16
  • 1970-01-01
相关资源
最近更新 更多