我是否应该在单行函数中添加async/await呢?

23 浏览
0 Comments

我是否应该在单行函数中添加async/await呢?

我应该像下面这样给一个单行函数添加async/await吗?\n

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

\n如果参数不需要异步调用,那么这样做是否是不必要的开销?我可以简单地这样写:\n

public Task GetFoo()
{
    return HandleAsync(....);
}

0
0 Comments

在上述内容中,提到了是否应该在单行函数中添加async/await的问题。原因是为了保持代码的一致性和清晰的风格。代码中的async/await表明这是一个异步函数,并返回一个Task。对于编译后的代码而言,几乎没有什么区别。如果你真的很在意减少冗余代码,那你可能不会使用C#。然而,这不仅是个人口味的问题,它对性能和可靠性至关重要。生成的IL代码将会有所不同。await生成一个状态机,其中包括一个不必要的线程同步上下文切换,可能会导致性能问题甚至死锁。

对于"我希望任何阅读我的代码的人都能理解这是一个异步函数"这一点,可以通过方法的名称来体现,而不是方法内的代码。就像HandleAsync一样,OP应该将自己的方法命名为GetFooAsync。使用第二个await是没有意义的,正如其他人所指出的,它实际上可能会导致问题。因此,应该在单行函数中添加async/await。

0
0 Comments

在这种情况下,是否应该将async/await添加到单行函数中取决于你是否仅仅想返回任务(task),以便可以在代码外部进行等待。如果是这样的话,那么不需要添加async/await。然而,对于异步任务,你应该使用await进行等待,以防止产生意外的副作用。具体取决于具体情况。

让我们来看看下面的例子:

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

这里返回了一个任务,所以在下载和处理任务时,我会使用await进行等待,例如:

public async Task DownloadAsync()
{
  Using(var stream = new MemoryStream(){
    await DownloadStream(stream); //在这里我需要等待而不是阻塞UI
  }
}

希望你能根据自己的情况理解并应用。

祝好运!

0
0 Comments

在这个问题中,原因是使用第二个重载方法,因为异步方法在后台会转换成一个状态机(额外的类)来处理带有等待的异步操作。因此,第一个方法增加了不必要的开销。第二个重载方法只是返回一个任务,你仍然可以等待它。

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

值得注意的是,await方法可能还会导致不必要的线程上下文切换(可能会有性能损失),因为没有使用ConfigureAwait(false)。

正如上面提到的-值得注意的是OP的要求。他是否需要HandleAsync的结果。还值得注意的是调用方法的更大上下文。它是与其他异步调用一起触发的,还是这个调用是孤立的。只有当所有线程非常忙碌时,上下文切换才会成为一个问题。

0