2017-10-17 47 views
4

我应该添加异步/等待对该像单行功能:我应该向单线函数添加异步/等待吗?

public async Task<T> GetFoo() 
{ 
    return await HandleAsync<T>(....); 
} 

或者,这是不必要的开销,如果该参数不需要一个asynchron电话,我可以简单的写:

public Task<T> GetFoo() 
{ 
    return HandleAsync<T>(....); 
} 
+2

这不是说你的函数是单行的,所以你不应该添加异步等待,这是关于你的要求,如果你想你的方法异步运行然后添加。 –

+0

不,因为添加它不会提高可读性。 – qxg

+0

@IpsitGaur因为HandleAsync已经异步运行,所以在这两种情况下执行异步。 – Horcrux7

回答

4

使用第二次重载,因为异步方法在幕后转换为astate机器(一个额外的类)以处理异步操作和等待。

所以第一种方法会增加不必要的开销。第二重载只是返回一个仍然可以等待的任务。

我不确定异常处理将如何改变,但我认为它没有改变。

+5

值得注意的是'await'方法也可能导致不需要的线程上下文切换(请参阅“可能的性能损失”),因为没有使用'ConfigureAwait(false)'。 – dymanoid

+2

正如上面提到的@Ipsut--值得注意的是OP的要求。他是否需要'HandleAsync'的结果。值得注意的是,调用该方法的更大范围。它是否被其他'async'调用触发,或者这个调用是否被隔离。如果所有线程都非常繁忙,上下文切换只会成为问题。 – ethane

0

好吧,这取决于。如果您只是想返回task,那么可以在此代码之外等待,然后不,您不需要添加它。但是,您应该等待您的异步任务,以获得不需要的副作用。这取决于每种情况。

让我们来看看下面的情况:

public Task DownloadStream(Stream target) 
{ 
return _downloader.ToStream(target); 
} 

将返回一个任务,所以在这里我想下载和处理它,那么我将等待它,即:

public async Task DownloadAsync() 
{ 
    Using(var stream = new MemoryStream(){ 
    await DownloadStream(stream); //<== here i NEED to wait and not block the UI 
    } 
} 

希望你可以在你的情况下解释它。

祝你好运!

0

我会在你描述的情况下添加异步/等待。很大程度上,这是一个一致的问题 - 我希望任何人阅读我的代码,了解这是一个异步函数并返回一个Task<T> - 和干净的样式。

你可能会觉得这是你不需要的额外仪式,没关系,这是个人品味的问题。但是,在编译的代码级别,如果有的话,几乎没有什么区别。当然,如果你对减少仪式感到非常紧张,你可能不会使用C#。

+3

这不是个人品味的问题,它对性能和可靠性至关重要。生成的IL代码将会不同。一个'await'产生一个状态机,包括一个不需要的线程同步上下文切换,这可能会导致性能问题甚至死锁。 – dymanoid

+0

_“我希望有人阅读我的代码,了解这是一个异步函数”_这是通过方法的名称完成的,而不是其内部的代码。就像Handle ** Async **一样,OP应该命名他的方法GetFoo ** Async **。使用第二个“await”是毫无意义的,正如其他人所说的那样,实际上可能会导致问题。 – Flater