web-dev-qa-db-ja.com

メソッド名での「非同期」接尾辞の使用は、「非同期」修飾子が使用されるかどうかに依存しますか?

メソッド名に「非同期」を付けるための規則は何ですか?

async修飾子で宣言されたメソッドに「非同期」サフィックスを追加する必要がありますかonly

public async Task<bool> ConnectAsync()

または、メソッドがTask<T>またはTaskを返すだけで十分ですか?

public Task<bool> ConnectAsync()
86
kasperhj

マイクロソフトのドキュメントからでも真実は曖昧だと思います。

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 voidAsyncの接尾辞が付いていることに気付いたら、おそらくそれをasync Taskに変えて、呼び出し側がそれを待ってから、Async

103
Luke Puplett

私のコードのほとんどが非同期で実行されている他のシステムを呼び出す多くのAPIサービスと他のアプリケーションを構築します。

私が従っている私自身の経験則は次のとおりです。

同じものを返す非非同期メソッドと非同期メソッドの両方がある場合は、非同期メソッドにAsyncを追加します。そうでない場合。

例:

1つの方法のみ:

public async Task<User> GetUser() { [...] }

2つの署名を持つ同じメソッド:

public User GetUser() { [...] }

public async Task<User> GetUserAsync() { [...] }

返されるデータは同じですが、異なるのはデータ自体ではなく、データを返す方法だけであるため、これは理にかなっています。

また、非同期メソッドを導入し、下位互換性を維持する必要があるため、この命名規則が存在すると思います。

新しいコードではAsyncサフィックスを使用しないでください。このスレッドで前述したように、戻り値の型StringまたはIntと同じくらい明白です。

37
Jonas Stensved

メソッド名に「非同期」を付けるための規則は何ですか。

タスクベースの非同期パターン(TAP) は、メソッドが常に_Task<T>_(またはTask)を返し、Asyncで名前を付けることを指示しますサフィックス;これは、asyncの使用とは別です。 Task<bool> Connect()asyncTask<bool> Connect()の両方がコンパイルして正常に実行されますが、勝ちました'TAP命名規則に従っていません。

メソッドにasync修飾子を含める必要がありますか、それともTaskを返すだけで十分ですか?

メソッドの本体に(戻り値の型や名前に関係なく)awaitが含まれている場合、mustasyncを使用します;コンパイラは「 'await'演算子は非同期メソッド内でのみ使用できます。..」と表示します。 _Task<T>_またはTaskを返すことは、asyncの使用を避けるのに十分ではありません。詳細については、 async(C#リファレンス) を参照してください。

つまりこれらの署名のうち正しいもの:

両方のasyncTask<bool> ConnectAsync()Task<bool> ConnectAsync()は、TAPの規則に適切に従います。 alwaysは常にasyncキーワードを使用できますが、「この非同期メソッドには 'await'演算子がなく、同期的に実行されます」というコンパイラ警告が表示されます。 "ボディがawaitを使用しない場合。

23
Ðаn

または、単にTaskを返すだけで十分ですか?

それ。ここでは、asyncキーワードは本当の問題ではありません。 asyncキーワードを使用せずに非同期を実装する場合、メソッドは一般的な意味で「非同期」のままです。

11
Servy

TaskTask<T>は両方とも待機可能なタイプであるため、これらはsome非同期操作を表します。または、少なくともそれらが表す必要があります。

接尾辞Asyncをメソッドに追加する必要があります。場合によっては(必ずしもすべてではない)、値を返さず、進行中の操作のラッパーを返します。そのラッパーは通常Taskですが、WindowsではRTになる可能性がありますIAsyncInfoAsync関数、彼または彼女は、そのメソッドの呼び出しがそのメソッドの結果から切り離されており、それに応じて動作する必要があることを知っています。

Taskを返すAsync接尾辞を持たないTask.DelayTask.WhenAllなどのメソッドがあることに注意してください。

また、fire and forget非同期メソッドを表すasync voidメソッドがあることに注意してください。メソッドはそのように構築されていることに注意する必要があります。

7
Toni Petrina

メソッドが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() { /* ... */ }
}
5
Fred

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なしで)知りません。

4
DavidRR