29

withobjの前後にオブジェクト参照 ( ) がある単純な C# async/await コードを見てみましょう。awaitConfigureAwait(false)

private async Task<SomeObject> AnAsyncLibraryMethod(SomeObject obj)
{
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    obj.Name = "Harry"; // <-- obj here

    // MAIN POINT
    var newSubObj = await FetchOverHttpAsync().ConfigureAwait(false);

    // Continuation here
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    obj.Name = "Sally"; // <-- same obj here
    return obj;
}

public class SomeObject { public string Name; }

ConfigureAwait(false)キャプチャされた元のコンテキストに継続をマーシャリングしない ことを意味するようです-わかりましたが、それは実際にはどういう意味ですか? 上記のコードを試してみたところ、正しく参照されました (別のスレッドで再開した場合でも)。obj

そのため、「コンテキスト」はスレッドの作業メモリ (つまり、スレッド ローカル ストレージ) ではないようです。では、「文脈」には何が含まれているのでしょうか。したがって、それは本当に何を意味するのでしょうか

継続をマーシャリングして、キャプチャした元のコンテキストに戻します

4

2 に答える 2

7

async紹介ブログ投稿で説明したように、「コンテキスト」は次のとおりです。

  • SynchronizationContext.Current、そうでない限りnull、その場合は
  • TaskScheduler.Current. 現在のタスク スケジューラがない場合は、スレッド プール コンテキストである とTaskScheduler.Current同じであることに注意してください。TaskScheduler.Default

ほとんどの場合、これは UI または ASP.NET 要求コンテキスト (両方のタイプSynchronizationContext) であるか、スレッド プール コンテキストです。タスク スケジューラのコンテキストが機能することはめったにありません。

このコンテキストは、継続をスケジュールするためにのみ使用されることに注意してください。マーシャリングでは何もしません。あなたの例objでは、ラムダ式から参照された場合と同じようにキャプチャされます。

于 2015-03-25T23:01:59.420 に答える