等待.NET完成任务的最佳方法是什么?

时间:2017-12-08 07:09:36

标签: c# .net multithreading asynchronous .net-4.5

这是我们的async方法,它在任务中执行了很长时间。

public async Task<int> LongRunningMethod(T p1, T p2, T p3);

我团队中的一些开发人员使用

Task t = Task.Factory.StartNew(LongRunningMethod(p1,p2,p3));
t.Wait();  //This will suspend main thread and wait for 't' to finish.

虽然有些人使用

await LongRunningMethod(p1,p2,p3);
// Here too, we simply 'await' till the method finishes.

注意:我们有一个异步任务,我们想等到该任务完成。

简而言之,在上述两种结构中哪一种最好?

2 个答案:

答案 0 :(得分:2)

使用Tasks的目的是从同一个上下文并行执行一些Task。如果你想从一个上下文开始一个长时间运行的任务,只想等待任务完成,你展示的两个方法都将以相同的方式工作。

但是如果你想在执行长时间运行的任务期间做任何其他操作, 你可以做到

{{1}}

但是如果需要长时间运行任务的结果来执行某些操作,则需要等待任务完成。 或者您可以使用 Task.ContinueWith()

答案 1 :(得分:2)

  

简而言之,在上述两种结构中哪一种最好?

您将了解影响,当系统可扩展性出现在图片中时,Task.Wait()await Task之间的差异是他们对待调用/执行线程的方式。当第一个阻塞直到完成发生时,使用await的另一个将释放调用者,但请注意它仅用于真正的异步调用,这意味着IO调用,网络调用,数据库调用不是在内存逻辑处理中,并公开异步API,这是在调用线程或上下文时释放的。对于真正的异步调用,它将使用Windows中的IO完成端口(排队机制)来执行异步管道。

如果在调用链结束时,最终方法不是真正的异步,则不会发生这种情况。

  

它们看起来几乎相似Waitawait

实际上,对于两个继续都将执行完成后,但让我们举一个例子,通常线程处理直接链接到系统中的核心数,使用TPL从池中调用这些线程并且数量有限线程可用。对于像100 K / sec请求这样的高可伸缩系统,Task.Wait()会很快超时运行一个长时间运行的方法,因为线程忙着闲置并被阻塞,他们不会接受新请求,但等待没有这样的阻塞发生了。

  

实际例子

  • Javascript,NodeJ默认情况下总是寻找异步请求,没有阻塞,这就是系统高度可扩展的原因

  • 同时考虑ConfigureAwait(false)和等待,然后它不会寻找相同的线程上下文来重新输入继续执行,这样效率更高

相关问题