Async なメソッドを待機しない場合の警告を消してみる

async なメソッドを呼び出す際は、多くの場合 await してその場で待機することが多いと思います。
しかし、稀に待たなくても良い場合もあるかもしれません。
そのような場合、await しなければ良いのですが、ただ await しないだけだと
「この呼び出しを待たないため、現在のメソッドの実行は、呼び出しが完了するまで続行します。呼び出しの結果に ‘await’ 演算子を適用することを検討してください。」
という警告が出てしまいます。中には警告を気にしない強い心の方もいらっしゃるかもしれませんが、できれば警告は消したいものです。

まずは、検証コードと実行結果を見てみましょう。

■ 検証コード

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Run1();
            Run2();
            Run3();
            Run4();
            Run5();
        }

        internal async static Task TestAsync(string no)
        {
            await Task.Delay(1000);
            Console.WriteLine($"{no}TestAsyncメソッド");
        }

        internal void Run1()
        {
            Console.WriteLine("Run1前");
            TestAsync("Run1");
            Console.WriteLine("Run1後");
        }

        internal async void Run2()
        {
            Console.WriteLine("Run2前");
            await TestAsync("Run2");
            Console.WriteLine("Run2後");
        }

        internal void Run3()
        {
            Console.WriteLine("Run3前");
            var t = TestAsync("Run3");
            Console.WriteLine("Run3後");
        }

        internal void Run4()
        {
            Console.WriteLine("Run4前");
            Func<Task> f = async () => { await TestAsync("Run4"); }; f();
            Console.WriteLine("Run4後");
        }

        internal void Run5()
        {
            Console.WriteLine("Run5前");
            TestAsync("Run5").ContinueWith(_ => { ; }) ;
            Console.WriteLine("Run5後");
        }
    }
}

■ 実行結果

Run1前
Run1後
Run2前
Run3前
Run3後
Run4前
Run4後
Run5前
Run5後
Run4TestAsyncメソッド
Run5TestAsyncメソッド
Run2TestAsyncメソッド
Run1TestAsyncメソッド
Run3TestAsyncメソッド
Run2後

まずは、Run1 メソッド。
これはただ await していないパターンです。実行結果を見ると意図通りに待機せずに実行されていますが、警告が出てしまいます。

ここで、警告に従って await したものが Run2 メソッドです。
実行結果を見ると当たり前ですが待機してしまっています。

次が Run3 メソッド。
これが、作法の様です。
警告が出ません。実行結果でも待機せずに実行されていることが確認できます。
ただ、この使わない変数に受ける方法は場合によっては、コーディング規約等で禁止されるかもしれません。

一応 Run4 メソッド。
警告も出ず、使わない変数も生みません。こんな変なことをする意味があるのかは不明ですが。
これも、コーディング規約によっては、ラムダ式禁止、Func<T> 使用禁止という項目があるかもしれません。

Run5 メソッド。
これが一番望ましいのかもしれません。しかしやはりラムダ式が出てくるので場合によっては使えないかもしれません。

■ 結論
頑張ってみましたが、素直にコメントをつけて変数に受けておくのが無難なのかもしれません。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中