22

先に進み、次のような機能があるとしましょう。

public class Test
{
    public async Task Finalize()
    {
        // We don't need this in this class, so empty body
    }

    /*
     * Additional methods snipped
     */
}

これは問題なく動作しますが、次のようなコンパイラの警告が表示されます。

この非同期メソッドには 'await'演算子がなく、同期的に実行されます。ブロッキングのないAPI呼び出しを待つために 'await'演算子を使用するか、またはバックグラウンドスレッドでCPUバウンドの作業を行うために 'await Task.Run(...)'を使用することを検討してください。

方法をあまり変更せずにこの警告を回避するための最善の方法は何でしょうか。この場合、メソッドが呼び出されるため、例外をスローすることはできませんが、この時点では絶対に何も起こらないということです。


  • asyncpublicと一緒に使用することはできませんinterfaces - Sriram Sakthivel

5 답변


13

ファイルに次のディレクティブを置くことができます。

#pragma warning disable 1998

しかし、私は警告をそのままにして、そのアドバイスを受けることをお勧めします。それは正当な理由のための警告です。

編集:あなたが1つの方法だけのために警告を無効にしたい場合は、これを行うことができます:

#pragma warning disable 1998
async Task Foo() {}
#pragma warning restore 1998


  • これは、1つの関数からだけではなく、この問題に関連するすべてのコンパイラ警告を無効にしませんか。 - Eisenhorn
  • その通り、#pragma warning restoreを使用することができます...編集させてください。 - Eren Ersönmez
  • このアプローチは実際のボディを追加しなくても非常にうまくいくようです。両方の答えを正しいとマークしますが、あなたは名誉を得るでしょう。ありがとうございます。 - Eisenhorn
  • 警告は、あなたが愚かなことをしたというサインです。愚かなことをしていないと100%確信できる場合にのみ警告を無効にするべきです。問題のコードはばかげているため、警告を無効にすると問題がさらに悪化しています。少なくともそれをコンパイルするときにはばかげたコードであることが警告されています。 #39;しないでください。 - Jon Hanna
  • @Jonその答えにはすでに警告がありますが、それが良い考えであるかどうかはわかりません。無視しているようです。) - Eren Ersönmez

57

このようにすると、コンパイラが警告を発するのではなく、警告が表示されなくなります。

あなたがそのようなコンパイラの警告を回避する必要があるなら、興味のある人のために:

public async Task DoStuff
{
    // This method should stay empty
    // Following statement will prevent a compiler warning:
    await Task.FromResult(0);
}


  • 実際の答えはここにあります。プラグマは、問題を回避するための最後の手段であり、時間をかけて維持するのは困難です。また、コードをコメントしてあなたの行動を説明してください。 - csaam
  • そうですね、私の答えは警告自体を防ぎますが、Erensの答えはミュートします'警告それで私のものは実際にはもう少し正確です、しかし私は私自身の答えをマークするという考えが嫌いです:P - Eisenhorn
  • なぜあなたがプラグマが最後の努力であるとあなたが言うのか本当によくわからないが、彼らはまさにそこに作られたものをする。警告があるので、警告に注意してコンパイラに伝えます。「これは注意が必要なことですが、本当に必要なのです」。私は個人的には、単にハックの警告を取り除くために偽のタスクを待つことを検討していますが、プラグマを使用すると、意図したとおりに物事を進めています。 - Robba
  • タスクを作成してからそのタスクを待機しても意味がありません。そのため、そのタスクを待機するタスクを作成できます。ただ削除するasyncそしてそのawait上記の回答から、同じシグネチャに一致し、最適化されないような無意味なコードを生成しません。 - Jon Hanna
  • この記事は、Task.CompletedTaskを提供する.NET 4.6より前に書かれました。 - ZunTzu

32

これは、非同期インターフェース用に同期(またはnoop)実装をしているときには、よくある問題です。

あなたが実装することができますTaskなしでの復帰方法async完成したキーワードを返すだけのキーワードTask、 など:

public Task FinalizeAsync()
{
  return Task.FromResult(0);
}

しかし、これでもまだTaskそれが呼ばれるたびに。あなた自身がこれをたくさんやっているのを見つけた場合、あなたは完成したものをキャッシュしたいかもしれませんTaskインスタンス。私のAsyncExライブラリはたくさんのタスク定数この目的のために:

public Task FinalizeAsync()
{
  return TaskConstants.Completed;
}

最後に、あなたは私のブログ記事を見てみるとよいでしょう。非同期処理いくつかの代替アプローチがあります。


  • 誰かが一緒に来て、それを指摘するコメントを追加することになっていたとしても、ここでははるかに最高の答えはここでasyncは実際のメソッドのシグネチャの一部ではないため、コードの呼び出しやインターフェイスのマッチングに影響はありません。完璧にすることができます。) - Jon Hanna
  • この記事は、Task.CompletedTaskを提供する.NET 4.6より前に書かれました。 - ZunTzu
  • @ JohnHannaああ説明をありがとう!派生クラスが非同期的に実装できるようにしたい空の仮想メソッドを宣言したときにこの問題に遭遇しましたが、仮想メソッドをasync。 - Toby J
  • @Tobyメソッドが非同期/待機アプローチによってタスクを作成するのか、それとも別のタスク作成メソッドがタスクを作成するのかは実装次第です。外部からは何の違いもなく、すべてのインターフェースがそれを主張することができます。 - Jon Hanna

4

以前の.NET 4.6では、ダミー値を返す必要がありましたが、これは必要ありません。しかし、これで次のようにできます。

public async Task MyFunctionAsync()
{
    // Some works here...
    await Task.CompletedTask;
}


  • この答えは何よりも優れています。 - Anoop H.N
  • 私は同意します、それはそれがとても新しくて見落とされがちな残念です。 - Jessica Pennell

-1

"async"を削除すると警告は消えます。

public class Test
{
    public void Finalize()
    {
        // We don't need this in this class, so empty body
    }
 }


  • あなたは非同期を取り除くことができます、ただタスクを返します、しかし戻り型を変更することは後で非同期を導入するオプションを制限する外部の呼び出し側にメソッドを変更します。 - Yishai

関連する質問

最近の質問