2017-01-06 21 views
-2

私はasync - awaitに行っているレポートの概念証明を作成しようとしています。 ConfigureAwait(false)とConfigureAwait(true)の違いは何ですか?

は、私は繰り返し、.NETフィドル上で実行しているコード

using System; 
using System.Threading.Tasks; 
using System.Threading; 

public class Program 
{ 
    static async Task CreateATaskThatPrintsWhichThread() 
    { 
     Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId); 
     await Task.Run(() => 
     { 
      Task.Delay(500); 
      Console.WriteLine("Thread on line inside bottom task action = {0}", Thread.CurrentThread.ManagedThreadId);       
     }); 
     Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId); 
    } 

    public static void Main() 
    { 
     Task.Run(async() => 
     { 
      Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId); 
      Task printStuff = CreateATaskThatPrintsWhichThread(); 
      printStuff.ConfigureAwait(true); 
      await printStuff; 
      Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId); 
     }).Wait(); 
    } 
} 

のサンプル曲を作ったとの結果が散発している:

Thread on line right before the bottom await = 14 
Thread on line right before the bottom await = 14 
Thread on line inside bottom task action = 28 
Thread on line right before the bottom await = 28 
Thread on line right before the bottom await = 28 


Thread on line right before the bottom await = 28 
Thread on line right before the bottom await = 28 
Thread on line inside bottom task action = 28 
Thread on line right before the bottom await = 28 
Thread on line right before the bottom await = 28 


Thread on line right before the bottom await = 28 
Thread on line right before the bottom await = 28 
Thread on line inside bottom task action = 53 
Thread on line right before the bottom await = 53 
Thread on line right before the bottom await = 28 

エトセトラ。そして、私が `printStuff.ConfigureAwait(false);に変更すると、

Thread on line right before the bottom await = 99 
Thread on line right before the bottom await = 99 
Thread on line inside bottom task action = 87 
Thread on line right before the bottom await = 36 
Thread on line right before the bottom await = 99 

Thread on line right before the bottom await = 45 
Thread on line right before the bottom await = 45 
Thread on line inside bottom task action = 36 
Thread on line right before the bottom await = 36 
Thread on line right before the bottom await = 45 

Thread on line right before the bottom await = 25 
Thread on line right before the bottom await = 25 
Thread on line inside bottom task action = 12 
Thread on line right before the bottom await = 12 
Thread on line right before the bottom await = 25 

結果があること、または多分私は.NETフィドルに、より良い例を作成するのに役立つ「すべきである」ものにの誰かの手掛かり私にはできますか?

(私はTask.Run内部の内側の線は、基本的にバックグラウンドスレッドで実行することが保証されていたと思ったので、私も混乱している)

+1

ロギングの半分がすでにロギングで使用されている他の文字列と区別できない文字列を使用することは非常に混乱していますか?私はそれが混乱しているのを知っているからです。 –

+1

なぜConfigureAwaitによって返されたタスクを破棄していますか? –

+3

問題を説明するコンパイラからの警告を受けているはずです。あなたは警告を無視しましたか?コードが正しく動作していないように見える場合は、コンパイラの警告を読むことを検討してください。これらの警告は、コードが正しく機能していない理由を伝えようとしています。 –

答えて

1

何の答えはまだありませんようなコメントはこれのほとんどをカバーし、しかし、私はあなたが答えたと思うのは、.ConfigureAwait(true)は、awaitの後に、コードが以前と同じスレッド上で続行されるということを間違って結論したということです。

場合によってはです。特に、メッセージ/ディスパッチャループの形式を持つものがあります。このような場合、継続コードが完了すると、キャプチャされたSynchronizationContextを使用して、ディスパッチャに要求をポストして、次にそのスレッドがそのスレッドでその実行を継続できるようにします。ループは通常、継続的かつ迅速に回転し、UIの問題に対応し、投稿が登録されると、繰り返しの1つを使用して継続を実行します。

コンソールアプリケーションにループがなく、SynchronizationContextがないため、継続を実行するタスクがスレッドプールにキューイングされ、使用可能なスレッドが実行されます。あなたは時々幸運になり、継続の前と同じ糸で終わるでしょうが、それはまさに偶然です。

+1

ここでは、コンソールアプリケーションがasync/awaitと異なる動作をする理由を説明する素晴らしいリンクがあります。 http://blog.stephencleary.com/2012/02/async-console-programs.html –

関連する問題