C# 在方法名称中使用“Async”后缀是否取决于是否使用了“async”修饰符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15951774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does the use of the "Async" suffix in a method name depend on whether the 'async' modifier is used?
提问by kasperhj
What is the convention for suffixing method names with "Async"?
使用“Async”为方法名称添加后缀的约定是什么?
Should the "Async" suffix be appended onlyto a method that is declared with the async
modifier?
“Async”后缀是否应该仅附加到使用async
修饰符声明的方法?
public async Task<bool> ConnectAsync()
Or is it enough that the method just returns Task<T>
or Task
?
或者该方法仅返回Task<T>
或返回就足够了Task
吗?
public Task<bool> ConnectAsync()
采纳答案by Luke Puplett
I think the truth is ambiguous even from Microsoft documentation:
我认为即使从 Microsoft 文档中,事实也是模棱两可的:
In Visual Studio 2012 and the .NET Framework 4.5, any method that is attributed with the
async
keyword (Async
in Visual Basic) is considered an asynchronous method, and the C# and Visual Basic compilers perform the necessary transformations to implement the method asynchronously by using TAP. An asynchronous method should return either aTask
or aTask<TResult>
object.
在 Visual Studio 2012 和 .NET Framework 4.5 中,任何带有
async
关键字(Async
在 Visual Basic 中)的方法都被视为异步方法,并且 C# 和 Visual Basic 编译器执行必要的转换以使用 TAP 异步实现该方法。异步方法应该返回一个Task
或一个Task<TResult>
对象。
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
That's not right already. Any method with async
is asynchronous and then its saying it should return either a Task
or Task<T>
- which isn't right for methods at the top of a call stack, Button_Click for example, or async void
.
那已经不对了。任何方法 withasync
都是异步的,然后它说它应该返回 a Task
or Task<T>
- 这对调用堆栈顶部的方法不正确,例如 Button_Click 或async void
.
Of course, you have to consider what is the point of the convention?
当然,你必须考虑约定的意义是什么?
You could say that the Async
suffix convention is to communicate to the API user that the method is awaitable. For a method to be awaitable, it must return Task
for a void, or Task<T>
for a value-returning method, which means only the latter can be suffixed with Async
.
您可以说Async
后缀约定是向 API 用户传达该方法是可等待的。对于可等待的方法,它必须返回Task
void 或Task<T>
返回值的方法,这意味着只有后者可以后缀为Async
.
Or you might say that the Async
suffix convention is to communicate that the method can return immediately, relinquishing the current thread to perform other work and potentially causing races.
或者您可能会说Async
后缀约定是为了传达该方法可以立即返回,放弃当前线程以执行其他工作并可能导致竞争。
This Microsoft doc quote says:
这个微软文档引用说:
By convention, you append "Async" to the names of methods that have an Async or async modifier.
按照惯例,您将“Async”附加到具有 Async 或 async 修饰符的方法的名称。
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
Which doesn't even mention that your own asynchronous methods returning Task
need the Async
suffix, which I think we all agree they do.
甚至没有提到您自己的异步方法返回Task
需要Async
后缀,我想我们都同意他们这样做。
So the answer to this question could be: both. In both cases, you need to append Async
to methods with async
keyword and that return Task
or Task<T>
.
所以这个问题的答案可能是:两者兼而有之。在这两种情况下,您都需要附加Async
到带有async
关键字和返回Task
或的方法Task<T>
。
I'm going to ask Stephen Toub to clarify the situation.
我要请斯蒂芬·图布澄清情况。
Update
更新
So I did. And here's what our good man wrote:
所以我做了。这是我们的好人所写的:
If a public method is Task-returning and is asynchronous in nature (as opposed to a method that is known to always execute synchronously to completion but still returns a Task for some reason), it should have an “Async” suffix. That's the guideline. The primary goal here with the naming is to make it very obvious to a consumer of the functionality that the method being invoked will likely not complete all of its work synchronously; it of course also helps with the case where functionality is exposed with both synchronous and asynchronous methods such that you need a name difference to distinguish them. How the method achieves its asynchronous implementation is immaterial to the naming: whether async/await is used to garner the compiler's help, or whether types and methods from System.Threading.Tasks are used directly (e.g. TaskCompletionSource) doesn't really matter, as that doesn't affect the method's signature as far as a consumer of the method is concerned.
Of course, there are always exceptions to a guideline. The most notable one in the case of naming would be cases where an entire type's raison d'etre is to provide async-focused functionality, in which case having Async on every method would be overkill, e.g. the methods on Task itself that produce other Tasks.
As for void-returning asynchronous methods, it's not desirable to have those in public surface area, since the caller has no good way of knowing when the asynchronous work has completed. If you must expose a void-returning asynchronous method publicly, though, you likely do want to have a name that conveys that asynchronous work is being initiated, and you could use the “Async” suffix here if it made sense. Given how rare this case should be, I'd argue it's really a case-by-case kind of decision.
I hope that helps, Steve
如果公共方法返回任务并且本质上是异步的(而不是已知始终同步执行完成但仍出于某种原因返回任务的方法),则它应该具有“异步”后缀。这就是指导方针。命名的主要目标是让功能的使用者非常明显地意识到被调用的方法可能不会同步完成其所有工作;它当然也有助于同步和异步方法公开功能的情况,以便您需要名称差异来区分它们。方法如何实现其异步实现与命名无关:是否使用 async/await 来获得编译器的帮助,或者是否来自 System.Threading 的类型和方法。
当然,指南总是有例外的。在命名的情况下,最值得注意的是整个类型的存在理由是提供以异步为中心的功能的情况,在这种情况下,在每个方法上都使用 Async 将是矫枉过正,例如 Task 本身产生其他任务的方法.
至于返回 void 的异步方法,将它们放在公共表面区域中是不可取的,因为调用者无法知道异步工作何时完成。但是,如果您必须公开公开返回 void 的异步方法,您可能确实希望有一个名称来表示正在启动异步工作,如果有意义,您可以在此处使用“Async”后缀。鉴于这种情况应该是多么罕见,我认为这实际上是一种逐案决定。
我希望这会有所帮助,史蒂夫
The succinct guidance from Stephen's opening sentence is clear enough. It excludes async void
because it is unusual to want to create a public API with such a design since the correct way to implement an asynchronous void is to return a plain Task
instance and let the compiler to its magic. However, if you did want a public async void
, then appending Async
is advised. Other top-of-stack async void
methods such as event handlers are usually not public and don't matter/qualify.
斯蒂芬开场白的简洁指导已经足够清楚了。它排除在外async void
是因为想要创建具有这种设计的公共 API 是不寻常的,因为实现异步 void 的正确方法是返回一个普通Task
实例并让编译器发挥其魔力。但是,如果您确实想要public async void
,则Async
建议附加。其他栈顶async void
方法(例如事件处理程序)通常不是公开的,也不重要/不合格。
For me, it tells me that if I find myself wondering about suffixing Async
on an async void
, I probably should turn it into an async Task
so that callers can await it, then append Async
.
对我来说,它告诉我,如果我发现自己Async
对 an 的后缀感到疑惑async void
,我可能应该将其转换为 anasync Task
以便调用者可以等待它,然后附加Async
.
回答by Dаn
What is the convention for suffixing method names with "Async".
使用“Async”后缀方法名称的约定是什么。
The Task-based Asynchronous Pattern (TAP)dictates that methods should always return a Task<T>
(or Task
) and be named with an Asyncsuffix; this is separate from the use of async
. Both Task<bool> Connect()
and async
Task<bool> Connect()
will compile and run just fine, but you won't be following the TAP naming convention.
基于任务的异步模式 (TAP)规定方法应始终返回Task<T>
(或Task
) 并使用Async后缀命名;这与使用async
. 双方Task<bool> Connect()
并会编译和运行得很好,但你不会是TAP命名约定以下。async
Task<bool> Connect()
Should the method contain the
async
modifier, or it enough that it just returns Task?
该方法是否应该包含
async
修饰符,或者它只返回 Task 就足够了?
If the body of the method (regardless of the return type or name) includes await
, you mustuse async
; and the compiler will tell you "The 'await' operator can only be used within an async method. ...". Returning Task<T>
or Task
is not "enough" to avoid using async
. See async (C# Reference)for details.
如果方法的主体(无论返回类型或名称如何)包括await
,则必须使用async
; 并且编译器会告诉您“'await' 运算符只能在异步方法中使用......”。返回Task<T>
或Task
不足以避免使用async
. 有关详细信息,请参阅async(C# 参考)。
I.e. which of these signatures are correct:
即这些签名中哪些是正确的:
Both async
Task<bool> ConnectAsync()
and Task<bool> ConnectAsync()
properly follow the TAP conventions. You could alwaysuse the async
keyword, but you'll get a compiler warning "This async method lacks 'await' operators and will run synchronously. ..." if the body doesn't use await
.
双方并妥善遵循TAP约定。您始终可以使用关键字,但是如果主体不使用.async
Task<bool> ConnectAsync()
Task<bool> ConnectAsync()
async
await
回答by Servy
or it enough that it just returns Task?
或者它只是返回任务就足够了?
That. The async
keyword isn't the real issue here. If you implement the asynchrony without using the async
keyword the method is still "Async", in the general sense.
那。该async
关键字是不是在这里真正的问题。如果您在不使用async
关键字的情况下实现异步,则在一般意义上,该方法仍然是“异步”。
回答by Toni Petrina
Since Task
and Task<T>
are both awaitable types, they represent someasynchronous operation. Or at least they should represent.
由于Task
和Task<T>
都是可等待类型,因此它们代表一些异步操作。或者至少他们应该代表。
You should add suffix Async
to a method which, in some cases (not necessarily all), doesn't return a value but rather returns a wrapper around an ongoing operation. That wrapper is usually a Task
, but on Windows RT it can be IAsyncInfo
. Follow your gut feeling and remember that if a user of your code sees the Async
function, he or she will know that the invocation of that method is decoupled from the result of that method and that they need to act accordingly.
您应该Async
向方法添加后缀,该方法在某些情况下(不一定是全部)不返回值,而是返回正在进行的操作的包装器。该包装器通常是Task
,但在 Windows RT 上它可以是IAsyncInfo
. 跟随您的直觉并记住,如果您的代码的用户看到该Async
函数,他或她就会知道该方法的调用与该方法的结果是分离的,并且他们需要相应地采取行动。
Note that there are methods such as Task.Delay
and Task.WhenAll
which return Task
and yet don't have the Async
suffix.
请注意,有些方法如Task.Delay
和Task.WhenAll
返回Task
但没有Async
后缀。
Also note that there are async void
methods which represent fire and forgetasynchronous method and you should better be aware that the method is built in such way.
另请注意,有些async void
方法代表了即发即忘的异步方法,您最好注意该方法是以这种方式构建的。
回答by DavidRR
In Asynchronous Programming with async and await (C#), Microsoft offers the following guidance:
在使用 async 和 await (C#) 进行异步编程中,Microsoft 提供了以下指导:
Naming Convention
By convention, you append "Async" to the names of methods that have an asyncmodifier.
You can ignore the convention where an event, base class, or interface contract suggests a different name. For example, you shouldn't rename common event handlers, such as
Button1_Click
.
命名约定
按照惯例,您将“Async”附加到具有async修饰符的方法的名称 。
您可以忽略事件、基类或接口协定建议不同名称的约定。例如,您不应重命名常见的事件处理程序,例如
Button1_Click
.
I find this guidance incomplete and unsatisfying. Does this mean that in the absence of the async
modifier, this method should be named Connect
instead of ConnectAsync
?
我发现这个指南不完整且不令人满意。这是否意味着在没有async
修饰符的情况下,这个方法应该被命名Connect
而不是ConnectAsync
?
public Task<bool> ConnectAsync()
{
return ConnectAsyncInternal();
}
I don't think so. As indicated in the concise answerby @Servyand the more detailed answerby @Luke Puplett, I believe that it is appropriate and indeed expected that this method shouldbe named ConnectAsync
(because it returns an awaitable). In further support of this, @John Skeetin this answerto another question appends Async
to the method name regardless of the presence of the async
modifier.
我不这么认为。正如指出的回答言简意赅由@Servy和更详细的解答由@Luke Puplett,我认为这是适当的,确实预计这一方法应该被命名为ConnectAsync
(因为它返回一个awaitable)。为了进一步支持这一点,@John Skeet在另一个问题的答案中附加Async
到方法名称,而不管async
修饰符是否存在。
Finally, on another question, consider this commentby @Damien_The_Unbeliever:
最后,在另一个问题,认为此评论的@Damien_The_Unbeliever:
async/await
are implementationdetails of your methods. It matters not one jot whether your method is declaredasync Task Method()
or justTask Method()
, so far as your callersare concerned. (In fact, you are free to change between these two at a later point in time without it being considered a breaking change.)
async/await
是你的方法的实现细节。就您的调用者而言,您的方法是声明的async Task Method()
还是只是Task Method()
一点都不重要。(事实上,您可以在稍后的时间点自由地在这两者之间进行更改,而不会被视为破坏性更改。)
From that, I infer that it is the asynchronous nature of the methodthat dictates how it should be named. The user of the method won't even know whether the async
modifier is used in its implementation (without the C# source code or CIL).
由此,我推断是方法的异步性质决定了它应该如何命名。该方法的用户甚至不知道async
在其实现中是否使用了修饰符(没有 C# 源代码或 CIL)。
回答by Fred
I would argue that it should use the Async-suffix if it returns a Task regardless if the method is declared with the async
modifier or not.
我认为它应该使用 Async 后缀,如果它返回一个任务,无论该方法是否使用async
修饰符声明。
The reason behind it being that the name is declared in the interface. The interface declares the return type which is a Task
. Then there are two implementations of that interface, one implementation implements it using the async
modifier, the other does not.
其背后的原因是名称是在接口中声明的。该接口声明了返回类型,即Task
. 然后该接口有两种实现,一种实现使用async
修饰符实现它,另一种则没有。
public interface IFoo
{
Task FooAsync();
}
public class FooA : IFoo
{
public Task FooAsync() { /* ... */ }
}
public class FooB : IFoo
{
public async Task FooAsync() { /* ... */ }
}
回答by Jonas Stensved
I build a lot API-services and other applications that call others systems where most of my code is running asynchronous.
我构建了很多 API 服务和其他应用程序,它们调用我的大部分代码异步运行的其他系统。
My own rule of thumb I'm following is:
我自己遵循的经验法则是:
If there is both non-async and async method that return the same thing I suffix the async one with Async. Otherwise not.
如果非异步和异步方法都返回相同的内容,我会将异步方法后缀为 Async。否则不行。
Examples:
例子:
Only one method:
只有一种方法:
public async Task<User> GetUser() { [...] }
Same method with two signatures:
具有两个签名的相同方法:
public User GetUser() { [...] }
public async Task<User> GetUserAsync() { [...] }
This makes sense since it's the same data that is returned but the only thing that differs is the way of returning data, not the data itself.
这是有道理的,因为返回的是相同的数据,但唯一不同的是返回数据的方式,而不是数据本身。
I also think this naming conventions exists due to the need to introduce async methods and still maintain backwards compatibility.
我也认为这种命名约定的存在是因为需要引入异步方法并仍然保持向后兼容性。
I argue that new code shouldn't use the Async suffix. It is just as obvious as return type of String, or Int as mentioned before in this thread.
我认为新代码不应该使用 Async 后缀。它与之前在此线程中提到的 String 或 Int 的返回类型一样明显。