サーチ…


async / awaitキーワードの擬似コード

単純な非同期メソッドを考えてみましょう:

async Task Foo()
{
    Bar();
    await Baz();
    Qux();
}

単純化すると、このコードは実際には次のことを意味します。

Task Foo()
{
    Bar();
    Task t = Baz();
    var context = SynchronizationContext.Current;
    t.ContinueWith(task) =>
    {
        if (context == null)
            Qux();
        else
            context.Post((obj) => Qux(), null);
    }, TaskScheduler.Current);

    return t;
}

これは、 async / awaitキーワードが存在する場合、現在の同期コンテキストを使用することを意味します。つまり、UI、Web、およびConsoleアプリケーションで正しく動作するライブラリコードを記述できます。

ソース記事

同期コンテキストを無効にする

同期コンテキストを無効にするには、 ConfigureAwaitメソッドを呼び出す必要があります。

async Task() Foo()
{
    await Task.Run(() => Console.WriteLine("Test"));
}

. . .

Foo().ConfigureAwait(false);

ConfigureAwaitは、デフォルトのSynchronizationContext取得動作を回避する手段を提供します。 flowContextパラメータにfalseを渡すと、待機した後にSynchronizationContextを使用して実行を再開できなくなります。

それはSynchronizationContextに関するすべてです。

なぜSynchronizationContextが重要なのでしょうか?

この例を考えてみましょう。

private void button1_Click(object sender, EventArgs e)
{
    label1.Text = RunTooLong();
}

このメソッドは、 RunTooLongが完了するまでUIアプリケーションをフリーズします。アプリケーションが応答しなくなります。

内部コードを非同期で実行することができます:

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() => label1.Text = RunTooLong());
}

しかし、このコードは内部ボディが非UIスレッドで実行される可能性があり、UIプロパティを直接変更してはならないため、このコードは実行されません。

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        var label1Text = RunTooLong();

        if (label1.InvokeRequired)
            lable1.BeginInvoke((Action) delegate() { label1.Text = label1Text; });
        else
            label1.Text = label1Text;
    });
}

今このパターンを使うことを常に忘れないでください。または、 SynchronizationContext.Postを試してみてください。

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        var label1Text = RunTooLong();
        SynchronizationContext.Current.Post((obj) =>
        {
            label1.Text = label1    Text);
        }, null);
    });
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow