将async添加到方法签名是一个重大改变吗?

ror*_*.ap 3 .net c# asynchronous async-await

在解决有关使用异步/等待多少的问题时,即"应该所有方法都返回Task吗?",这个答案的作者MatíasFidemraizer声称,即使你的方法目前只做同步的东西,它仍然应该返回一个任务因此,如果你以后再做异步操作,"你可以把它变成实际的异步操作,而不会影响整个代码库".这是有道理的,但如果我实际上在等待某事,我必须添加async方法签名.所以我们谈论的是:

public Task WhateverAsync()
{
    return Task.FromResult(true);
}
Run Code Online (Sandbox Code Playgroud)

public async Task WhateverAsync()
{
    return await AwaitableSomething();
}
Run Code Online (Sandbox Code Playgroud)

添加async方法签名是一个重大改变吗?

Ste*_*ary 6

即使你的方法目前只做同步的东西,它仍然应该返回一个任务

我不同意.如果您的方法是同步的,那么它应该具有同步API.如果您的方法是异步的,那么它应该有一个异步API.

不过,我会同意,同步方法应该有一个Task-returning签名,如果他们是在一个接口/基类中定义,并有未来实现/覆盖可能需要使用一个体面的可能性await.

将async添加到方法签名是一个重大改变吗?

刚添加async?不它不是.考虑Task在接口中定义的 - 返回方法的情况:它可以有或没有实现async.

但是,正如我在博客中描述的那样,语义上存在一些可能的差异.最值得注意的是异常处理是不同的.如果你不小心,一个天真的同步实现可能会直接抛出异常,而不是返回一个错误的任务.一旦你创建了这个方法async,异常将是一个错误的任务,并且不再直接抛出.

所以,这真的是一个关于语义可能发生变化的问题.我认为天真的同步语义是错误的,因为该方法具有异步签名.例如,同步方法具有异步签名,因此调用者认为它将捕获异常并返回故障任务是合理的.因此,如果同步实现具有这些(易于导致的)错误,那么从技术上讲,添加async 是一个突破性的变化.