メソッド名に「非同期」を付けるための規則は何ですか?
async
修飾子で宣言されたメソッドに「非同期」サフィックスを追加する必要がありますかonly?
public async Task<bool> ConnectAsync()
または、メソッドがTask<T>
またはTask
を返すだけで十分ですか?
public Task<bool> ConnectAsync()
マイクロソフトのドキュメントからでも真実は曖昧だと思います。
Visual Studio 2012および.NET Framework 4.5では、
async
キーワード(Visual BasicのAsync
)に関連付けられているメソッドは非同期メソッドと見なされ、C#およびVisual Basicコンパイラーは実行しますTAPを使用して非同期にメソッドを実装するために必要な変換。非同期メソッドは、Task
またはTask<TResult>
オブジェクトを返す必要があります。
http://msdn.Microsoft.com/en-us/library/hh873177(v = vs.110).aspx
すでにそうではありません。 async
を含むメソッドは非同期であり、Task
またはTask<T>
のいずれかを返す必要があると言っています。これは、呼び出しスタックの最上位のメソッド、Button_Click for例、またはasync void
。
もちろん、コンベンションのポイントは何かを考慮する必要がありますか?
Async
接尾辞の規則は、メソッドが待機可能であることをAPIユーザーに伝えることです。メソッドを待機可能にするには、voidに対してTask
を返すか、値を返すメソッドに対してTask<T>
を返す必要があります。つまり、後者にのみAsync
を接尾辞として付けることができます。
または、Async
接尾辞規則は、メソッドがすぐに戻り、現在のスレッドを放棄して他の作業を実行し、潜在的に競合を引き起こす可能性があることを伝えることです。
このMicrosoftのドキュメンテーションの引用:
慣例により、Asyncまたはasync修飾子を持つメソッドの名前に「非同期」を追加します。
http://msdn.Microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention
Task
を返す独自の非同期メソッドがAsync
サフィックスを必要とすることすら言及していません。
したがって、この質問に対する答えは次のとおりです。どちらの場合も、Async
キーワードを使用してasync
またはTask<T>
を返すメソッドにTask
を追加する必要があります。
私はスティーブン・トーブに状況を明確にするよう頼むつもりです。
更新
だから私はやった。そして、ここに私たちの善人が書いたものがあります:
パブリックメソッドがTask-returningであり、本質的に非同期である場合(常に完了するまで常に同期して実行されることがわかっているが、何らかの理由でTaskを返すメソッドとは対照的)、「Async」サフィックスが必要です。それがガイドラインです。ここでの命名の主な目標は、呼び出されるメソッドがすべての作業を同期的に完了しない可能性が高いことを機能のコンシューマーに非常に明確にすることです。もちろん、同期メソッドと非同期メソッドの両方で機能を公開する場合にも役立ちます。そのため、それらを区別するには名前の違いが必要です。メソッドが非同期実装をどのように実現するかは、命名に重要ではありません:async/awaitを使用してコンパイラのヘルプを取得するか、System.Threading.Tasksの型およびメソッドを直接使用するか(例:TaskCompletionSource)は重要ではありません。メソッドのコンシューマーに関する限り、メソッドの署名には影響しません。
もちろん、ガイドラインには常に例外があります。命名の場合の最も注目すべきものは、タイプ全体の存在理由が非同期に焦点を合わせた機能を提供することである場合です。その場合、すべてのメソッドで非同期を持つことは過剰です。他のタスクを生成するタスク自体のメソッド。
Voidを返す非同期メソッドに関しては、非同期の作業がいつ完了したかを呼び出し側が知る良い方法がないため、それらをパブリックの表面領域に置くことは望ましくありません。ただし、voidを返す非同期メソッドを公開する必要がある場合は、非同期作業が開始されていることを示す名前が必要になる可能性があります。意味がある場合は、ここで「非同期」サフィックスを使用できます。このケースがどれほどまれであることを考えると、それは本当にケースバイケースの決定であると主張します。
それがお役に立てば幸いです、スティーブ
スティーブンの冒頭文からの簡潔なガイダンスは十分に明確です。非同期ボイドを実装する正しい方法は、プレーンなTask
インスタンスを返し、コンパイラーをその魔法にまかせることであるため、このようなデザインのパブリックAPIを作成することは珍しいため、async void
は除外されます。 。ただし、public async void
が必要な場合は、Async
を追加することをお勧めします。イベントハンドラなどのその他のスタックのasync void
メソッドは、通常は公開されておらず、重要ではありません。
私にとっては、async void
にAsync
の接尾辞が付いていることに気付いたら、おそらくそれをasync Task
に変えて、呼び出し側がそれを待ってから、Async
。
私のコードのほとんどが非同期で実行されている他のシステムを呼び出す多くのAPIサービスと他のアプリケーションを構築します。
私が従っている私自身の経験則は次のとおりです。
同じものを返す非非同期メソッドと非同期メソッドの両方がある場合は、非同期メソッドにAsyncを追加します。そうでない場合。
例:
1つの方法のみ:
public async Task<User> GetUser() { [...] }
2つの署名を持つ同じメソッド:
public User GetUser() { [...] }
public async Task<User> GetUserAsync() { [...] }
返されるデータは同じですが、異なるのはデータ自体ではなく、データを返す方法だけであるため、これは理にかなっています。
また、非同期メソッドを導入し、下位互換性を維持する必要があるため、この命名規則が存在すると思います。
新しいコードではAsyncサフィックスを使用しないでください。このスレッドで前述したように、戻り値の型StringまたはIntと同じくらい明白です。
メソッド名に「非同期」を付けるための規則は何ですか。
タスクベースの非同期パターン(TAP) は、メソッドが常に_Task<T>
_(またはTask
)を返し、Asyncで名前を付けることを指示しますサフィックス;これは、async
の使用とは別です。 Task<bool> Connect()
とasync
Task<bool> Connect()
の両方がコンパイルして正常に実行されますが、勝ちました'TAP命名規則に従っていません。
メソッドに
async
修飾子を含める必要がありますか、それともTaskを返すだけで十分ですか?
メソッドの本体に(戻り値の型や名前に関係なく)await
が含まれている場合、mustasync
を使用します;コンパイラは「 'await'演算子は非同期メソッド内でのみ使用できます。..」と表示します。 _Task<T>
_またはTask
を返すことは、async
の使用を避けるのに十分ではありません。詳細については、 async(C#リファレンス) を参照してください。
つまりこれらの署名のうち正しいもの:
両方のasync
Task<bool> ConnectAsync()
とTask<bool> ConnectAsync()
は、TAPの規則に適切に従います。 alwaysは常にasync
キーワードを使用できますが、「この非同期メソッドには 'await'演算子がなく、同期的に実行されます」というコンパイラ警告が表示されます。 "ボディがawait
を使用しない場合。
または、単にTaskを返すだけで十分ですか?
それ。ここでは、async
キーワードは本当の問題ではありません。 async
キーワードを使用せずに非同期を実装する場合、メソッドは一般的な意味で「非同期」のままです。
Task
とTask<T>
は両方とも待機可能なタイプであるため、これらはsome非同期操作を表します。または、少なくともそれらが表す必要があります。
接尾辞Async
をメソッドに追加する必要があります。場合によっては(必ずしもすべてではない)、値を返さず、進行中の操作のラッパーを返します。そのラッパーは通常Task
ですが、WindowsではRTになる可能性がありますIAsyncInfo
。 Async
関数、彼または彼女は、そのメソッドの呼び出しがそのメソッドの結果から切り離されており、それに応じて動作する必要があることを知っています。
Task
を返すAsync
接尾辞を持たないTask.Delay
やTask.WhenAll
などのメソッドがあることに注意してください。
また、fire and forget非同期メソッドを表すasync void
メソッドがあることに注意してください。メソッドはそのように構築されていることに注意する必要があります。
メソッドがasync
修飾子で宣言されているかどうかに関係なく、Taskを返す場合はAsync-suffixを使用する必要があると主張します。
その背後にある理由は、名前がインターフェイスで宣言されていることです。インターフェイスは、Task
である戻り値の型を宣言します。次に、そのインターフェイスには2つの実装があり、1つの実装はasync
修飾子を使用して実装し、もう1つは実装しません。
public interface IFoo
{
Task FooAsync();
}
public class FooA : IFoo
{
public Task FooAsync() { /* ... */ }
}
public class FooB : IFoo
{
public async Task FooAsync() { /* ... */ }
}
asyncとawaitを使用した非同期プログラミング(C#) で、Microsoftは次のガイダンスを提供します。
命名規則
慣例により、async修飾子を持つメソッドの名前に「非同期」を追加します。
イベント、基本クラス、またはインターフェースコントラクトが別の名前を示唆する慣習は無視できます。たとえば、_
Button1_Click
_などの一般的なイベントハンドラーの名前は変更しないでください。
このガイダンスは不完全で不満だと思います。これは、async
修飾子がない場合、このメソッドの名前はConnect
ではなくConnectAsync
でなければならないということですか?
_public Task<bool> ConnectAsync()
{
return ConnectAsyncInternal();
}
_
そうは思いません。 簡潔な回答 by @ Servy 以上に示されているように 詳細な回答 by @ Luke Puplett このメソッドは適切であり、実際に期待されていますshouldConnectAsync
(awaitableを返すため)という名前が付けられています。これをさらにサポートするために、 @ John Skeet in この回答 は別の質問にAsync
が存在するかどうかに関係なく、メソッド名にasync
を追加します。修飾子。
最後に、 別の質問 で、- @ Damien_The_Unbeliever による このコメント を検討します。
_
async/await
_は実装メソッドの詳細です。あなたのメソッドがasync Task Method()
で宣言されているか、単にTask Method()
で宣言されているかは、callersに関する限り、重要ではありません。 (実際、後の時点で、これら2つの間を自由に変更できます。これは、重大な変更とは見なされません。)
それから、私はメソッドの非同期性がそれがどのように命名されるべきかを決定するのだと推測します。メソッドのユーザーは、その実装でasync
修飾子が使用されているかどうかさえ(C#ソースコードまたはCILなしで)知りません。