4

async-awaitスレッドコンテキストを保持し、例外転送なども処理することはすでに知っています(これは非常に役立ちます)。

ただし、次の例を検討してください。

/*1*/   public async Task<int> ExampleMethodAsync()
/*2*/   {
/*3*/       var httpClient = new HttpClient(); 
/*4*/      
/*5*/       //start async task...
/*6*/       Task<string> contentsTask = httpClient.GetStringAsync("http://msdn.microsoft.com");
/*7*/   
/*8*/       //wait and return...  
/*9*/       string contents = await contentsTask;
/*10*/   
/*11*/       //get the length...
/*12*/       int exampleInt = contents.Length;
/*13*/       
/*14*/       //return the length... 
/*15*/       return exampleInt;
/*16*/   }

asyncメソッド ( ) が IO 操作である場合httpClient.GetStringAsync(上記のサンプルのように) だから - 私はこれらのものを得る:

  • 呼び出し元スレッドはブロックされていません
  • IO操作があるため、ワーカースレッドが解放されます (IO 完了ポート...) (GetStringAsync を使用TaskCompletionSourceし、新しいスレッドを開きません)
  • 保持されたスレッド コンテキスト
  • 例外がスローされます

しかし、httpClient.GetStringAsync(IO操作)の代わりに、(別のスレッドでの重い計算にバインドされた操作)のタスクがある場合はどうなりますかCalcFirstMillionsDigitsOf_PI_Async

ここで得られるものは次のとおりです。

  • 保持されたスレッド コンテキスト
  • 例外がスローされます
  • 呼び出し元スレッドはブロックされていません

しかし、操作を実行する別のスレッド (並列スレッド) がまだあります。CPUはメインスレッドと操作の間で切り替えています。

私の診断は正しいですか?

4

3 に答える 3

3

あなたの分析は正しいですが、2番目の部分の文言asyncは、ワーカースレッドを作成しているように聞こえますが、そうではありません。

ライブラリ コードでは、実際には同期メソッドの同期を維持する必要があります。同期メソッドを非同期で (たとえば、UI スレッドから) 消費する場合は、次を使用して呼び出します。await Task.Run(..)

于 2013-08-26T12:07:08.513 に答える