这是我们的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.
注意:我们有一个异步任务,我们想等到该任务完成。
简而言之,在上述两种结构中哪一种最好?
答案 0 :(得分:2)
使用Tasks的目的是从同一个上下文并行执行一些Task。如果你想从一个上下文开始一个长时间运行的任务,只想等待任务完成,你展示的两个方法都将以相同的方式工作。
但是如果你想在执行长时间运行的任务期间做任何其他操作, 你可以做到
{{1}}
但是如果需要长时间运行任务的结果来执行某些操作,则需要等待任务完成。 或者您可以使用 Task.ContinueWith()
答案 1 :(得分:2)
简而言之,在上述两种结构中哪一种最好?
您将了解影响,当系统可扩展性出现在图片中时,Task.Wait()
和await Task
之间的差异是他们对待调用/执行线程的方式。当第一个阻塞直到完成发生时,使用await
的另一个将释放调用者,但请注意它仅用于真正的异步调用,这意味着IO调用,网络调用,数据库调用不是在内存逻辑处理中,并公开异步API,这是在调用线程或上下文时释放的。对于真正的异步调用,它将使用Windows中的IO完成端口(排队机制)来执行异步管道。
如果在调用链结束时,最终方法不是真正的异步,则不会发生这种情况。
它们看起来几乎相似
Wait
和await
实际上,对于两个继续都将执行完成后,但让我们举一个例子,通常线程处理直接链接到系统中的核心数,使用TPL从池中调用这些线程并且数量有限线程可用。对于像100 K / sec请求这样的高可伸缩系统,Task.Wait()会很快超时运行一个长时间运行的方法,因为线程忙着闲置并被阻塞,他们不会接受新请求,但等待没有这样的阻塞发生了。
实际例子
Javascript,NodeJ默认情况下总是寻找异步请求,没有阻塞,这就是系统高度可扩展的原因
同时考虑ConfigureAwait(false)
和等待,然后它不会寻找相同的线程上下文来重新输入继续执行,这样效率更高