没有异步或等待的Task.Run

时间:2015-07-09 14:51:39

标签: c# task

如果我把我正在调用的一些方法从我的控制器调到Task.Run这究竟是做什么的?我没有使用异步功能而且我没有使用等待。

...
FunctionOne();
FunctionTwo();
return View(FunctionThree().Result);
}

private void FunctionOne()
{
        Task.Run(() =>
        {
            ....
        }
}

private void FunctionTwo()
{
        Task.Run(() =>
        {
            ....
        }
}

private Task<MyType> FunctionThree()
{
        return Task.Run(() =>
        {
            ....
        }
}

1 个答案:

答案 0 :(得分:2)

正如@LasseVKarlsen解释的那样,此代码尝试并行执行函数一,二和三。 Task.Run立即对线程池上的指定工作进行排队,.Result将阻塞调用线程,直到其Task(并且只有它的任务)完成为止。

这可能是也可能不是一个好的设计。有些事情需要考虑:

  • 您正在使用线程池中的四个线程来执行此操作。如果这个动作负载很重 - 即。它经常被调用 - 池中可用线程的数量可能成为新的瓶颈。
  • 函数One和Two具有基本上无限制的运行时,因为没有客户端会等待它们。如果向这些函数添加了太多逻辑,则可能会再次耗尽池中的线程。
  • 正如@LasseVKarlsen所提到的,这可能会导致deadlock
  • 如果这些是CPU限制功能,那么并行执行这些功能可能无法为您带来任何好处。 (但是,不等待One和Two可能会很多地购买客户端。)如果下面有I / O操作(例如网络调用,数据库调用,文件系统调用),您可能需要查看改为Using an Asynchronous Controller in ASP.NET MVC
  • 正如@StephenCleary指出的那样,ASP.NET并没有跟踪你的线程。如果发生了回收(例如编辑web.config时),它将始终完成功能三作为请求的一部分,但One和Two可能会被取消。

这些注意事项是否表明您的设计发生了变化,这是一个问题,即每项功能的作用,使用时间以及它们对您的业务逻辑的重要性。