Task.Run()不是异步运行的

本文关键字:异步 运行 Run Task | 更新日期: 2023-09-27 17:49:42

我有一个ASP。. NET MVC 3站点连接到WCF服务。WCF服务独立于站点,并托管在Windows服务中。大多数调用都是同步的,所以等待WCF完成它的工作不是问题。

然而,其中一个(已经实现的)调用花费的时间太长了,而且,因为它本质上不直接输出任何东西,我想把它放在服务上,忘记它。

所以我把代码改成:

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  WcfServiceProxy.DoSlowCalculation(calculationOptions);
  ViewBag.Started = true;
  return View();
}

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  Task.Run(() =>
  {
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });
  ViewBag.Started = true;
  return View();
}

,据我所知,它应该启动一个异步请求,并立即返回。然而,执行是完全同步的,UI被冻结,直到操作结束。

我错过了什么明显的东西?


更新:

另外,请注意,我不希望将服务器实现更改为异步实现,只是为了在调用站点上取消对服务的同步调用。

此外,我注意到StartSlowCalculation方法完成执行,但服务器直到服务方法完成执行才返回响应。

WCF服务代理只是做:

public void DoSlowCalculation(CalculationOptions calculationOptions)
{
   //some logging code
   Channel.DoSlowCalculation(calculationOptions);
}

所以它是完全同步的,但这并不重要,因为它应该在一个独立的线程上执行。

Task.Run()不是异步运行的

任务操作可以在调用线程中运行,这取决于taskScheduler的决定。为了帮助TaskScheduler对长时间运行的调用做出正确的决定,您可以指定任务创建选项TaskCreationOptions.LongRunning

你可以检查任务操作是否在一个单独的线程中运行:

int launchedByThreadId = Thread.CurrentThread.ManagedThreadId;
int launchedInThreadId = -1;
Task.Run(() =>
  {
    launchedInThreadId = Thread.CurrentThread.ManagedThreadId;
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });
// then compare whether thread ids are different

顺便说一句,您是否使用任何Task.Wait()操作?它也会阻塞调用线程。

编辑:

Task.Factory.StartNew()保证使用另一个线程而不是调用线程吗?

所以尝试使用Task.Factory.StartNew()并指定取消令牌,即使你不需要它,听起来很奇怪,但似乎这保证任务最终不会在调用线程中运行。如果我说错了请指正

我以前这样做过。

最健壮的方法是使用异步控制器,或者最好是一个独立的服务,如WCF服务。

但根据我的经验,我只需要做"简单"的一行任务,比如审计或报告。

在这个例子中,最简单的方法——启动一个任务:

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  //Some Synchronous code.
   Task.Factory.StartNew(() =>
  {
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });
  ViewBag.Started = true;
  return View();
}

这是一个简单的例子。你可以启动任意多的任务,同步它们,当它们完成时得到通知,等等。

详细信息请参见此链接。

https://msdn.microsoft.com/en-us/library/dd321439 (v = vs.110) . aspx