2017-11-28 3 views
-2

私はコードの下に実行すると、出力はこれです: Output when printed till 500 私は300まで実行すると、出力はこれです: Output when printed till 300 私は100まで実行すると、出力はこれです: Output when printed till 100これらの2つの方法は、ほぼ同時に開始されていますか?

これは両方の方法ことを意味していますほぼ同時に開始されましたか?

これが当てはまる場合、async-awaitで並列性を達成するには、なぜ並列ライブラリが必要なのでしょうか?

using System; 
using System.Threading.Tasks; 


class Program 
{ 
    public static void PrintX() 
    { 
     for (int i = 0; i < 500; i++) { Console.Write("x"); } 
    } 

    public static void PrintY() 
    { 
     for (int i = 0; i < 500; i++) { Console.Write("y"); } 
    } 

    public async Task RunAsync() 
    { 
     var t1 = Task.Run(() => PrintY()); 
     var t2 = Task.Run(() => PrintX()); 
     await t1; 
     await t2; 
    } 

    static void Main(string[] args) 
    { 
     Task t = new Program().RunAsync(); 
     t.Wait(); 
    } 
} 
+2

コードサンプルをa)完全にインデントする(名前空間宣言を削除するか、クラスを字下げする)か、b)意味のあるメソッド名を付けることができますか? (CountForwardメソッドはカウントせず、PrintXメソッドはyを出力します...) –

+1

しかし、はい、基本的に同時実行を取得しています。 TPLでは、物事をより慎重に管理することができます。 1つのソースからの作業項目を限定された作業セットに分散させることなどが含まれます。 –

+2

コンソール出力は、並行性を可視にする最悪の可能性の1つです。ある時点で出力を同期させる必要があります。 – grek40

答えて

4

最終的にあなたはここのスレッドプールを慈悲にしています。あなたは2つのアイテム(Task.Run)を待ち行列に入れました。そして、それらは将来のある時にピックアップされ、サービスされます。開始時に非決定論的であり、使用可能なスレッドの数やその他の要因に依存します。

と同時に何も保証されていない(おそらく開始順序でさえも)。 awaitは彼らの完了に対してトリガされます - あなたは(あなたがawaitを呼び出したり、かどうか)await呼び出すのでどのような方法でそれらに影響を与えません。それらは並行して実行される可能性がありますが、ほとんどの場合、最初に開始されたものが完了してから2番目のものを開始しようとすると、個々に高速で実行される可能性が最も高いです。それらは、同じスレッド上で連続して実行されることもあります(管理されたスレッドIDを出力することは、これを見る方法になります)。

なぜParallelが必要なのか:まず、async/awaitに先行します。第二にそれは多くのことを可能にする大規模化並列化 - 固定最大並列化を含む同時処理で大きなシーケンスを実行するようなもの。

main: 1 
y: 3 
x: 4 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
xxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 

間違い同時、しかし::他の実行は非常に異なる出力を表示することができます

はちょうどそれ同時ことができることを示すために、ここで私は出力にEnvironment.CurrentManagedThreadIdを追加した実走行からの出力です

+0

私は両方のメソッドの中にThread.Sleep(50)を置くと、両方のメソッドが並列に実行されているようです。 – Lyrk

+2

@Lyrkあなたは睡眠なしでもそれを得ることができます - 上記の編集を参照してください。ポイントは、同時性について話し始めるとすぐに、非決定論を得ることです。 AとBを指定すると、 "A、B"、 "B、A"、 "AとBは同時にAと並行して実行"、または "AとBはBと並行して実行" –

+0

タスクを使ってメソッドを開始するときです。Run()は、別のスレッドで開始されます。 (これはマイクロソフトの文書の中でこう言われている)だから、私は上記のコードでは、これら二つのメソッドを異なるスレッドで実行するようにコンピュータに命じる。代わりに、私はこれらの関数を並列ライブラリに入れたら、別々のスレッドから開始し、同時にasync-awaitの代わりに並列ライブラリでこれを達成することの違いは何ですか?私は両方の違いが何か別のスレッドで開始するのですか? – Lyrk

関連する問題