任务和异步的区别 [英] Difference between Task and async

查看:165
本文介绍了任务和异步的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#提供了创建异步方法有两种方法:

C# provides two ways of creating asynchronous methods:

方法1:

static Task<string> MyAsyncTPL() {
  Task<string> result = PerformWork();
  return result.ContinueWith(t => MyContinuation());
}

方法2:

static async Task<string> MyAsync() {
  string result = await PerformWork();
  return MyContinuation();
}

上述两种方法都是异步并达到同样的事情。所以,我什么时候应该选择一种方法比其他?是否有使用一个比其他任何指导或优点?

Both the above methods are async and achieves the same thing. So, when should I choose one method over the other? Are there any guidelines or advantages of using one over the other?

推荐答案

我推荐你使用等待,而不是 ContinueWith 。虽然 - 在一个较高的水平 - 他们是非常相似的,他们也有不同的默认行为

I recommend you use await rather than ContinueWith. While - at a high level - they are very similar, they also have different default behavior.

在使用 ContinueWith ,你选择一个低层的抽象。尤其是,这里有一些危险点,这就是为什么我不推荐使用 ContinueWith ,除非该方法的很简单的(或你的名字是斯蒂芬Toub):

When you use ContinueWith, you are choosing a lower-level abstraction. In particular, here are some "danger points", and this is why I don't recommend using ContinueWith unless the method is really simple (or your name is Stephen Toub):

  • Exceptions raised from async Task methods are placed on the returned task; exceptions raised from non-async methods are propagated directly.
  • await will by default will resume the async method in the same "context". This "context" is SynchronizationContext.Current unless it is null, in which case it is TaskScheduler.Current. This means that if you call MyAsync on a UI thread (or within an ASP.NET request context), then MyContinuation will also execute on the UI thread (or in that same ASP.NET request context). I explain this more on my blog.
  • You should always specify a scheduler for ContinueWith; otherwise, it will pick up TaskScheduler.Current, which can cause surprising behavior. I describe this problem in detail on my blog. That post is about StartNew; but ContinueWith has the same "non-default default scheduler" problem described in that post.
  • await uses appropriate behavior and optimization flags that are not set by default in ContinueWith. For example, it uses DenyChildAttach (to ensure asynchronous tasks are not mistakenly used as parallel tasks) and ExecuteSynchronously (an optimization).

总之,使用 ContinueWith 异步任务的唯一原因是为了保存的非常的少量的时间和内存(通过避免异步状态机的开销),作为交换你的code是的可读性和可维护性。

In short, the only reason to use ContinueWith for asynchronous tasks is to save an extremely small amount of time and memory (by avoiding the async state machine overhead), and in exchange your code is less readable and maintainable.

通过一个非常简单的例子,你可能会侥幸成功;但随着全碟指出的,只要你有循环的 ContinueWith code只是爆炸的复杂性。

With an extremely simple example, you might get away with it; but as Jon Skeet pointed out, as soon as you have loops the ContinueWith code simply explodes in complexity.

这篇关于任务和异步的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆