在方法名称后缀“ Async”的约定是什么?
应在“异步”后缀被追加只到被声明为一个方法async
修改?
public async Task<bool> ConnectAsync()
抑或是足够的方法只返回Task<T>
或Task
?
public Task<bool> ConnectAsync()
在方法名称后缀“ Async”的约定是什么?
应在“异步”后缀被追加只到被声明为一个方法async
修改?
public async Task<bool> ConnectAsync()
抑或是足够的方法只返回Task<T>
或Task
?
public Task<bool> ConnectAsync()
Answers:
我认为,即使从Microsoft文档来看,事实也是模棱两可的:
在Visual Studio 2012和.NET Framework 4.5中,使用
async
关键字(Async
在Visual Basic中)赋予的任何方法均被视为异步方法,并且C#和Visual Basic编译器执行必要的转换,以使用TAP异步实现该方法。异步方法应返回Task
或Task<TResult>
对象。
http://msdn.microsoft.com/zh-CN/library/hh873177(v=vs.110).aspx
那还不对。具有的任何方法async
都是异步的,然后说应该返回a Task
或Task<T>
-不适用于调用堆栈顶部的方法,例如Button_Click或async void
。
当然,您必须考虑公约的意义是什么?
您可以说Async
后缀约定是为了向API用户传达该方法是可以等待的。为了使方法可以等待,它必须返回Task
一个空Task<T>
值或一个返回值的方法,这意味着只能为后者加上后缀Async
。
或者,您可能会说Async
后缀约定是为了传达该方法可以立即返回,放弃当前线程来执行其他工作并可能导致竞争的信息。
此Microsoft Doc引用说:
按照约定,您可以在具有Async或async修饰符的方法名称后附加“ Async”。
http://msdn.microsoft.com/zh-CN/library/hh191443.aspx#BKMK_NamingConvention
甚至没有提到您自己的异步方法返回Task
需要Async
后缀,我认为我们都同意它们需要后缀。
因此,这个问题的答案可能是:两者都有。在这两种情况下,您都需要Async
使用async
关键字将方法追加到返回Task
或的方法上Task<T>
。
我要请Stephen Toub澄清情况。
更新资料
所以我做了。这就是我们的好男人写的:
如果公用方法是返回任务的并且本质上是异步的(与已知的方法始终同步执行到完成但由于某种原因仍返回Task的方法相反),则该公用方法应具有“异步”后缀。那是指导方针。这里的命名的主要目的是使功能的使用者非常清楚,所调用的方法可能不会同步完成其所有工作。当然,在同步和异步方法都公开功能的情况下,它也很有帮助,因此您需要区分名称以区分它们。该方法如何实现其异步实现与命名无关紧要:是否使用async / await来获得编译器的帮助,或者是否直接使用System.Threading.Tasks中的类型和方法(e。G。TaskCompletionSource)并不重要,因为就该方法的使用者而言,它不会影响该方法的签名。
当然,指南总是有例外。在命名的情况下,最值得注意的情况是整个类型的存在理由是要提供以异步为重点的功能,在这种情况下,在每个方法上都具有异步将是过大的,例如Task上的方法会产生其他Tasks 。
至于返回空值的异步方法,最好不要将它们放在公共区域,因为调用者没有很好的方法来知道异步工作何时完成。但是,如果必须公开公开一个返回空值的异步方法,则可能确实想要一个传达异步工作正在启动的名称,如果可以的话,可以在此处使用“异步”后缀。考虑到这种情况应该是多么罕见,我认为这实际上是个案决定。
我希望有帮助,史蒂夫
斯蒂芬开场白的简洁指导很清楚。它async void
之所以排除在外是因为用这种设计来创建公共API是不寻常的,因为实现异步void的正确方法是返回一个纯Task
实例并让编译器发挥作用。但是,如果您确实需要public async void
,则Async
建议添加。其他堆栈顶部async void
方法(例如事件处理程序)通常不是公开的,并且不重要/不合格。
对我来说,它告诉我,如果我发现自己想Async
对an进行后缀async void
,我可能应该将其转换为an,async Task
以便调用者可以等待它,然后追加Async
。
PersonString
或者PriceDecimal
为什么使用GetAsync
- API消费者的异步API的不用担心这个作为请求总是返回所有任务完成后,无论如何。这很愚蠢,让我很烦。但这只是另一项约定,没人真正知道为什么会出现它。
我建立了许多API服务和其他应用程序,这些应用程序调用了我的大多数代码都异步运行的其他系统。
我遵循的经验法则是:
如果同时有非异步方法和异步方法返回相同的内容,那么我在异步后缀中加上Async。否则不行。
例子:
只有一种方法:
public async Task<User> GetUser() { [...] }
具有两个签名的相同方法:
public User GetUser() { [...] }
public async Task<User> GetUserAsync() { [...] }
这是有道理的,因为它返回的是相同的数据,但唯一不同的是返回数据的方式,而不是数据本身。
我也认为存在这种命名约定是因为需要引入异步方法,并且仍然保持向后兼容。
我认为新代码不应使用Async后缀。正如该线程前面提到的String或Int的返回类型一样明显。
在方法名称后缀“ Async”的约定是什么?
基于任务的异步模式(TAP)规定方法应始终返回Task<T>
(或Task
)并以异步后缀命名;这与async
。双方Task<bool> Connect()
并会编译和运行得很好,但你不会是TAP命名约定以下。async
Task<bool> Connect()
该方法应包含
async
修饰符,还是足以使其返回Task?
如果方法的主体(与返回类型或名称无关)包括在内await
,则必须使用async
; 然后编译器会告诉您“'await'运算符只能在异步方法中使用。...”。返回Task<T>
或Task
不够用以避免使用async
。有关详细信息,请参见异步(C#参考)。
即以下哪些签名是正确的:
双方并async
Task<bool> ConnectAsync()
Task<bool> ConnectAsync()
妥善遵循TAP约定。您可以始终使用async
关键字,但是如果主体不使用,则会收到一个编译器警告“此异步方法缺少'await'运算符,并且将同步运行。...” await
。
async
关键字。
async
问题的第二部分是@Servy是否使用关键字。
async
修饰符。另请参见OP示例,public async Task<bool> ConnectAsync()
(带有async
修饰符)与public Task<bool> ConnectAsync()
(不带有async
修饰符)。在这两种情况下,方法名称本身都有后缀“ Async”。
Task
或具有的方法名称后附加“异步” async Task
。
由于Task
和Task<T>
都是等待类型,因此它们表示一些异步操作。或者至少他们应该代表。
您应该Async
在方法中添加后缀,该方法在某些情况下(不一定是全部)不会返回值,而是返回正在进行的操作的包装器。该包装通常是一个Task
,但在Windows RT上可以IAsyncInfo
。遵循您的直觉,并记住,如果您的代码用户看到了该Async
函数,则他或她将知道该方法的调用与该方法的结果是分离的,并且他们需要采取相应的行动。
请注意,有诸如Task.Delay
和Task.WhenAll
这样的方法会返回Task
,但没有Async
后缀。
还要注意,有些async void
方法代表着火,而忘记了异步方法,您应该更好地意识到该方法是以这种方式构建的。
我认为如果该方法返回的是Task,则无论该方法是否用A声明,它都应使用Async后缀。 async
修饰符。
其背后的原因是在接口中声明了名称。接口声明返回类型为Task
。然后,该接口有两种实现,一种实现是使用async
修饰符实现的,另一种则不是。
public interface IFoo
{
Task FooAsync();
}
public class FooA : IFoo
{
public Task FooAsync() { /* ... */ }
}
public class FooB : IFoo
{
public async Task FooAsync() { /* ... */ }
}
在带有异步和等待的异步编程(C#)中,Microsoft提供以下指导:
命名约定
按照约定,将“异步”附加到具有异步的方法的名称上 修饰符。
您可以忽略事件,基类或接口协定建议使用其他名称的约定。例如,您不应重命名常见事件处理程序,例如
Button1_Click
。
我发现此指南不完整且不令人满意。这是否意味着在没有async
修饰符的情况下,应将此方法命名为Connect
而不是ConnectAsync
?
public Task<bool> ConnectAsync()
{
return ConnectAsyncInternal();
}
我不这么认为。正如指出的回答言简意赅由@Servy和更详细的解答由@Luke Puplett,我认为这是适当的,确实预计这一方法应该被命名为ConnectAsync
(因为它返回一个awaitable)。为了进一步支持这一点,@John Skeet在另一个问题的答案中,Async
无论async
修饰符是否存在,都将附加到方法名称上。
最后,在另一个问题,认为此评论的@Damien_The_Unbeliever:
async/await
是方法的实现细节。就调用者而言,是否声明您的方法async Task Method()
还是just 无关紧要。(实际上,您可以在稍后的时间自由在这两者之间进行更改,而不会被认为是重大更改。)Task Method()
由此推断,正是方法的异步性质决定了应如何命名。该方法的用户甚至不知道async
在其实现中是否使用了修饰符(没有C#源代码或CIL)。