web-dev-qa-db-ja.com

非同期デリゲートを待つ方法

MVAビデオの1つで、次の構造を見ました:

static void Main(string[] args)
{
    Action testAction = async () =>
    {
        Console.WriteLine("In");
        await Task.Delay(100);
        Console.WriteLine("After first delay");
        await Task.Delay(100);
        Console.WriteLine("After second delay");
    };

    testAction.Invoke();
}

実行結果は次のようになります。

In
Press any key to continue . . .

それは完全にコンパイルされますが、今のところそれを待つ方法はありません。 Thread.SleepまたはConsole.ReadKey呼び出し後ですが、それは私が望むものではありません。

では、このデリゲートをどのように変更して待機可能にする必要がありますか?

そのようなデリゲートの実用的な使用法はありますか?

31
Uriil

何かを待つためには、awaitableでなければなりません。 voidはそうではないので、Actionデリゲートを待つことはできません。

Awaitableは、GetAwaiterメソッドを実装する任意のタイプで、INotifyCompletionや_Task<T>_など、ICriticalNotifyCompletionまたはTaskのいずれかを実装するタイプを返します。

デリゲートで待機する場合は、_Func<Task>_を使用します。これは、次のシグネチャを持つ名前付きメソッドと同等です。

_public Task Func()
_

したがって、待つために、メソッドを次のように変更します。

_static void Main(string[] args)
{
    Func<Task> testFunc = async () =>
    {
        Console.WriteLine("In");
        await Task.Delay(100);
        Console.WriteLine("First delay");
        await Task.Delay(100);
        Console.WriteLine("Second delay");
    };
}
_

そして今、あなたはそれを待つことができます:

_await testFunc();
_
49
Yuval Itzchakov

「非同期voidはトップレベルのイベントハンドラー専用です」、

http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only

4
Lex Li