メソッド名での「Async」サフィックスの使用は、「async」修飾子が使用されているかどうかによって異なりますか?


106

メソッド名の接尾辞に「非同期」の規則はありますか?

「Async」サフィックスは、修飾子を使用して宣言されたメソッドにのみ追加する必要がありasyncますか?

public async Task<bool> ConnectAsync()

それとも、この方法だけで返すことは十分ですTask<T>Task

public Task<bool> ConnectAsync()

4
名前付けの部分については、TAPのドキュメントに次のように記載されています。TAPの非同期メソッドには、操作名の後にAsyncサフィックスが含まれます。たとえば、get操作のGetAsync。非同期サフィックスを持つそのメソッド名がすでに含まれているクラスにTAPメソッドを追加する場合は、代わりにサフィックスTaskAsyncを使用してください。たとえば、クラスにすでにGetAsyncメソッドがある場合は、GetTaskAsyncという名前を使用します。
James Manning、

4
[OK]を、私は「非同期メソッドの命名規則」の質問のタイトルで混乱していたと思います
ジェームズ・マニングを

1
これは不完全に構成された質問です。物議を醸す人々、あいまいな答え。
ルークPuplett 2014

4
多くの人がそれを誤解していて、質問されている実際の事柄について議論しているので、それは2つの部分からなる質問なのかどうか疑問に思います。
ルークプレット2014

2
@DavidRR今日まで、私はこの質問が明らかに引き起こした混乱の程度をまだ理解していません。あなたの編集が混乱の中で何らかの順序をもたらし、それがあなたを助け、そしておそらく他の人を助けることができるなら、私はあなたの編集があなたを歓迎します。質問が古くなりすぎて、ここで質問したときに自分の考え方を思い出すことがほとんどできないため、元の意図はそれほど重要ではありません。ルークの答えは、すべてが混乱したわけではないことを反映しています。とても役に立った。
kasperhj 2016年

回答:


127

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

Visual Studio 2012および.NET Framework 4.5では、asyncキーワード(AsyncVisual Basicの場合)に起因するメソッドは非同期メソッドと見なされ、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などでは正しくありませんasync void

もちろん、大会のポイントは何ですか?

あなたは、と言うことができAsync接尾辞規則は方法がawaitableあるAPIの利用者に伝えることです。メソッドが待機可能であるためには、それはTaskvoidまたはTask<T>値を返すメソッドのために返す必要があります。つまり、メソッドにのみ接尾辞を付けることができますAsync

またはあなたはそれを言うかもしれません Asyncサフィックスの規約は、メソッドがすぐに戻り、現在のスレッドを放棄して他の作業を実行し、競合を引き起こす可能性があることを通知することです。

このマイクロソフトのドキュメントの引用は言う:

慣例として、Asyncまたはasync修飾子を持つメソッドの名前に「Async」を追加します。

http://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_NamingConvention

それはあなたが返す独自の非同期メソッドTaskAsyncサフィックスを必要とすることさえ言及していません。


したがって、この質問に対する答えは次のようになります。どちらの場合も、キーワードを使用Asyncしてメソッドに追加する必要があり、それによってor asyncが返されます。TaskTask<T>


状況を明らかにするようにスティーブン・トウブに依頼します。

更新

だから私はしました。そして、ここに私たちの善人が書いたものがあります:

パブリックメソッドがTask-returningであり、本質的に非同期である場合(常に完了まで同期的に実行されることがわかっていても、何らかの理由でTaskを返すメソッドとは対照的)、「Async」というサフィックスが必要です。それがガイドラインです。ここでの命名の主な目的は、呼び出されているメソッドがすべての作業を同期的に完了しない可能性があることを機能の利用者に非常に明白にすることです。もちろん、機能が同期メソッドと非同期メソッドの両方で公開されているため、それらを区別するために名前の違いが必要な場合にも役立ちます。メソッドがその非同期実装をどのように実現するかは、命名には重要ではありません。async/ awaitを使用してコンパイラーのヘルプを取得するか、System.Threading.Tasksの型とメソッドを直接使用するか(e。g。TaskCompletionSource)は、メソッドのコンシューマに関する限り、メソッドのシグネチャに影響を与えないため、実際には問題になりません。

もちろん、ガイドラインには常に例外があります。名前付けの場合の最も注目すべきものは、型全体の存在理由が非同期に焦点を合わせた機能を提供することである場合です。この場合、すべてのメソッドに非同期を設定することは過剰です。たとえば、他のタスクを生成するタスク自体のメソッド。

voidを返す非同期メソッドについては、呼び出し側が非同期処理がいつ完了したかを知るための適切な方法がないため、それらをパブリックサーフェス領域に置くことは望ましくありません。ただし、voidを返す非同期メソッドをパブリックに公開する必要がある場合は、非同期作業が開始されていることを伝える名前を付けた方がよいでしょう。意味がある場合は、ここで「非同期」サフィックスを使用できます。このケースがどれほどまれであるかを考えると、それは実際にはケースバイケースの決定であると私は主張します。

それが役に立てば幸い

スティーブンの冒頭の文章からの簡潔なガイダンスは十分に明確です。async void非同期voidを実装する正しい方法はプレーンなTaskインスタンスを返してコンパイラーを魔法にかけることなので、そのような設計でパブリックAPIを作成することは珍しいため、これは除外されます。ただし、が必要な場合はpublic async void、追加することAsyncをお勧めします。async voidイベントハンドラーなど、その他のスタックの最上位メソッドは、通常はパブリックではなく、重要ではありません。

私にとって、の接尾辞について疑問に思っている場合Asyncasync void、おそらくそれをに変えてasync Task、発信者がそれを待つことができるようにしてから、を追加する必要があることを教えてくれますAsync


20
まあ、残念なことに、メソッド呼び出しのコンパイル時間チェックはありません。私はメソッドに名前を付ける場合は取得またはGetAsyncと使用していないのawaitの呼び出し側から、コンパイル、ビルドに失敗します。この大会はとてもSILLYで、本当に好きなものを避けるような多くのMicrosoftスタイルガイドライン、逆行PersonStringPriceDecimal、なぜ使用GetAsync-要求は、常にすべてのタスクを完全とにかく後に返すよう非同期APIの必要性はない。この心配のAPIの消費者。そのばかげて本当に私を悩ませます。しかし、それがなぜそこにあるのか誰も本当に知らない、それは単なる別の慣習です。
Piotr Kula

2
@ppumkin:Stephenが指摘したように、メソッドは本質的にasync / awaitを使用せずに簡単に非同期にすることができるため、呼び出し元には、機能が非同期で実行されるかどうかの名前以外の表示はありません。
はんぼう2017

6
@ppumkin:デフォルトでは、非同期メソッドを待機しないと、コンパイル時の警告が発生します。ビルドエラーではありません。
ダスティンクリーブランド

7
この慣習はばかげています。メソッドが非同期であることを示す3つの自動表示があります。1.戻り値の型はTaskです。2.コード補完により、待機可能なヒントが表示されます。3.緑の下線が引かれ、コンパイラ警告が表示され、IDEから警告が表示されます。だから私は@ppumkinに完全に同意します。Async-suffixは、public Lazy <Customer> CustomerLazyのようなプロパティを記述した場合と同様に、ばかげています。誰がこれをするでしょう!??
マルコ

2
:@Marco私はそれが最高の場所だと思ったが、それとの係合を持っていない私は私が得るだろうと思って、GitHubの上でこのアイデアを提起github.com/dotnet/core/issues/1464
ルークPuplett

68

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

私が従う私自身の経験則は:

同じものを返す非非同期メソッドと非同期メソッドの両方がある場合は、非同期メソッドにAsyncのサフィックスを付けます。そうでない場合。

例:

1つの方法のみ:

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

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

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

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

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

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

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


8
特に、通常は「非同期」にする必要があることに同意します。この場合、サフィックスは冗長です-コードの90%に追加する意味は何ですか。)
Bartosz

3
これが最良の解決策です。気付かずに、私は自分のAPIで同じ方法を行ってきました。
マルコ

2
これは、非同期アプリケーションのすべてのメソッドに「非同期」で接尾辞を付けるよりもはるかに優れています
Mariusz Jamro

この手法の問題は、後で非同期でないバージョンを作成する場合、それ以外の場合に優先される「GetUser()」名を使用できないことです。
David

3
これは実際的な方法です。async修飾子を持つすべてのメソッドにAsyncを追加するのは、ハンガリー語表記2019だけです。後で非同期でないバージョンを追加する場合は、@ Davidで、メソッドの名前を変更して命名規則に従うか、それを行わないでください。
Skrymsli

25

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

タスクベースの非同期パターン(TAP)メソッドは、常に返すことを命ずるTask<T>(またはTask)で命名され非同期サフィックス。これはの使用とは別ですasyncTask<bool> Connect()とはどちらも正常にコンパイルおよび実行されますが、TAPの命名規則に従っていません。asyncTask<bool> Connect()

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

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

つまり、これらの署名のどれが正しいですか。

両方と適切TAPの規則に従ってください。キーワードはいつでも使用できますが、本文でを使用しないと、「この非同期メソッドには「待機」演算子がなく、同期して実行されます...」というコンパイラ警告が表示されます。asyncTask<bool> ConnectAsync()Task<bool> ConnectAsync()asyncawait


1
彼は、asyncキーワードを使用するかどうかではなく、メソッド名に「非同期」を追加するかどうかについて言及しています。
サービー2013

1
@Servyがキーワードを使用するかどうかasyncは、質問の2番目の部分です。
Corak

2
@Servy 2つの部分からなる質問です。最初に言ったように、メソッド名に「非同期」を追加するかどうかです。2番目の部分は、async修飾子を使用するかどうかです。OPの例public async Task<bool> ConnectAsync()async修飾子あり)とpublic Task<bool> ConnectAsync()async修飾子なし)も参照してください。メソッド自体には、どちらの場合でも「Async」というサフィックスが付いています。
Corak

2
2つの部分からなる質問ではありません。問題は、「非同期」を返すメソッドの名前Taskまたはを持つメソッドの名前に追加する必要があることasync Taskです。
kasperhj

3
@lejon:質問を改善する必要があります。「対」コードスニペットは、それが唯一の違いであるため、質問(全体)が非同期に関するものであることを明確にします。
2013

11

それともタスクを返すだけですか?

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


7

以来TaskTask<T>両方awaitableタイプがあり、それらを表現するいくつかの非同期操作を。または、少なくともそれらを表す必要があります。

Asyncメソッドにサフィックスを追加する必要があります。メソッドは、場合によっては(必ずしもすべてではない)値を返さず、進行中の操作のラッパーを返します。そのラッパーは通常a Taskですが、Windows RTでは可能ですIAsyncInfo。コードのユーザーがAsync関数を見ると、直感に倣って、そのメソッドの呼び出しがそのメソッドの結果から切り離され、それに応じて動作する必要があることがわかります。

Task.Delayand などのメソッドがありTask.WhenAll、戻り値Taskがあり、Asyncサフィックスがないことに注意してください。

また、起動して非同期メソッドを忘れるasync voidメソッドがあることにも注意してください。メソッドはそのように構築されていることに注意してください。


6

メソッドがasync修飾子で宣言されているかどうかに関係なく、タスクが返される場合は、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キーワードは実装の詳細であり、メソッドの内部の一部であり、その名前や外部に影響を与えるべきではないと思います。
アルKepp

5

では非同期とのawaitと非同期プログラミング(C#) 、マイクロソフトは、以下のガイダンスを提供しています:

命名規則

慣例により、非同期修飾子を持つメソッドの名前に「非同期」を追加します 。

イベント、基本クラス、またはインターフェイスコントラクトが別の名前を提案している規則は無視できます。たとえば、などの一般的なイベントハンドラの名前は変更しないでくださいButton1_Click

このガイダンスは不​​完全であり、満足のいくものではありません。これは、async修飾子がない場合、このメソッドのConnect代わりに名前を付ける必要があることを意味しConnectAsyncますか?

public Task<bool> ConnectAsync()
{
    return ConnectAsyncInternal();
}

私はそうは思いません。@Servyによる簡潔な回答@Luke Puplettによる詳細な回答に示されているように、このメソッドに名前を付けることが適切であり、実際に予期されています(待機可能なメソッド返されるため)。これをさらにサポートでは、@ジョンスキート、この答え別の質問には、追加かかわらずの存在のメソッド名に修正。ConnectAsyncAsyncasync

最後に、別の質問で@ Damien_The_Unbelieverによるこのコメントを検討してください

async/awaitある実装あなたの方法の詳細が表示されます。呼び出し元に関する限り、メソッドが宣言されているかどうかasync Task Method()だけTask Method()で問題はありません。(実際、これらの2つの間で、重大な変更と見なされることなく、後から自由に変更できます。)

それから、メソッドの命名方法を決定するのはメソッドの非同期の性質であると推測します。メソッドのユーザーは、async修飾子がその実装で使用されているかどうかさえ知りません(C#ソースコードまたはCILなし)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.