2014-04-20 36 views
6

我试图很好地理解异步/等待,并且想清除一些混淆。可有人请解释什么将是下面的执行方面的区别:异步/等待执行差异

// version 1 
public Task Copy(string source, string destination) { 
    return Task.Run(() => File.Copy(source, destination)); 
} 

public async Task Test() { 
    await Copy("test", "test2");  
    // do other stuff 
} 

和:

// version 2 
public async Task Copy(string source, string destination) { 
    await Task.Run(() => File.Copy(source, destination)); 
} 

public async Task Test() { 
    await Copy("test", "test2"); 
    // ... 
} 

他们是否导致相同的代码,为什么我会写一个比其他?

+1

可能是一个重复:http://stackoverflow.com/q/21033150/1768303 – Noseratio

+1

@Noseratio是的,这的确是,也Erics答案是一个“大开眼界”,抱歉的dup,没有找到任何东西(不确定如何制定搜索:P) –

+2

@DimitarDimitrov,IMO,除了状态机的开销之外,最主要的区别是[异常传播逻辑](http://stackoverflow.com/a/21082631/1768303) 。 – Noseratio

回答

8

首先让我先说两点代码都是而不是一样。

您的版本1代码将仅创建一个“状态机”,因为它仅包含等待Test方法。

您的版本2代码将为CopyTest方法创建两个“状态机”,这会增加一些开销。

为什么我们使用async方法?简单就是让我们的代码在处理“异步任务”时可读,优雅。它使我们的代码更优秀,避免回调和延续等

让我们打破什么Copy方法做,我们回答这个问题 我们是否真的需要它是async

Copy方法只是委托调用Task.Run返回,最终达到对File.Copy的完成完成的任务。所以意图很明确,我们需要一个通知File.Copy完成的任务。这种方法可以满足您的所有需求,无需按照预期方式运行即可使用async

那么,你什么时候需要async

当您需要在早期任务完成时继续执行某些代码时,您需要异步(继续)。

例子:

public async Task Test() 
{ 
    await Copy("test", "test2"); 
    DoPostCopied(whatever); 
    await DoPostCopied2();//Etc 
} 

你可以仅仅通过反编译两个版本验证async和非异步方法之间的差异。它太长,不会被读取,所以我跳过了这里。

结论:仅在需要时使用async。在这种情况下,版本1更好,您应该比版本2更喜欢它。

+0

+1指出他们是不一样的 –

+1

@AmitJoki我想我们需要为op提供+1以及完成有趣的问题 –

+0

。确实这是一个很好的问题 –