5日間楽しいパラレルおよびマルチスレッドC#プログラミング - 意識パラレルの最初の日

マルチコアの時代の到来により、並行開発は、ますますその強力なパワーを発揮します!並列プログラム、システムリソースをフルに活用を使用し、プログラムのパフォーマンスを向上させます。System.Threading.Tasks:.NET 4.0では、Microsoftは新しい名前空間を提供してくれます。パラレルを理解し、使用するために - 並列開発について多くのこと、今日の最も基本的かつ簡単に導入する最初のがあります。

、パラレル使用

パラレルおよび以下のForEach中には3つの一般的な方法を呼び出すには、があります。

1、Parallel.Invokeは、
これが最も簡単でシンプルなシリアルコードの並列化です。

ここでは、知識のポイントについて話をするストップウォッチの使用は、最近、それを説明するために、今日は何か最後にストップウォッチ、ストップウォッチを見つけることができない一部の人がいるということです。

あなたはそれが最初の名前空間を参照する必要があります使用したいコントロール名付けたSystem.Diagnosticsでストップウォッチ。

次のようにその使用は次のとおりです。

VARストップウォッチ=新しいストップウォッチ(); //インスタンスのストップウォッチを作成します。

stopWatch.Start(); //タイマーを開始

stopWatch.Stop(); //は、クロックを停止

stopWatch.Reset(); //ストップウォッチをリセット

stopWatch.Restart(); //リスタートストップウォッチを停止しました

stopWatch.ElapsedMilliseconds //はミリ秒単位で、現在の時間差に最初からストップウォッチを取得します

この知識のあまりを使用して、ストップウォッチの詳細を知りたい、それについてはBaiduに行くされ、多くのオンライン情報があります。

以下は、全体を入力しParallel.Invoke方法の騒ぎを導入し始めた、最初の新しいコンソールアプリケーションを作成し、以下のように、クラスを追加します。

public class ParallelDemo
      {
         private Stopwatch stopWatch = new Stopwatch();

         public void Run1()
         {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
         }
         public void Run2()
         {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
         }

         public void ParallelInvokeMethod()
         {
            stopWatch.Start();
            Parallel.Invoke(Run1, Run2);
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Restart();
            Run1();
            Run2();
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
         }
}

コードは、新しいファーストクラスを追加し、簡単であり、クラス内の二つの方法、RUN1とRUN2を書き込み、それぞれ、試験方法ParallelInvokeMethodを書き込み、メッセージを出力し、一定時間待機し、RUN1 RUN2二つの方法をコールし、その後、mainメソッドの呼び出しで、どのように実行されている時には、次の外観は:
ここで説明する絵を書きます
我々はParallel.Invoke方法が最長である、わずか3秒で呼び出している間、それは、5秒以上である必要があり、通常の通話を推測することができるはずですこの方法は、効率がたくさん改善されている、方法が並行して実行されることが分かります。

2、Parallel.For

クラスに次のようなこの方法および循環機能のためにそれをテストするためのメソッドを追加します。コードは以下の通りであります:

public void ParallelForMethod()
     {
            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
               for (int j = 0; j < 60000; j++)
               {
                  int sum = 0;
                  sum += i;
               }
            }
            stopWatch.Stop();
            Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            Parallel.For(0, 10000, item =>
            {
               for (int j = 0; j < 60000; j++)
               {
                  int sum = 0;
                  sum += item;
               }
            });
            stopWatch.Stop();
            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

     }

2つのサイクルを書いた、いくつかのことを行うには意味がありませんが、主な目的は、次の図の主な方法、業績を呼び出すのと同じ方法で、CPU時間を消費している:
ここで説明する絵を書きます
あなたが見ることができ、Parallel.Forのために一人で過ごした時間よりも早くパフォーマンスの向上は非常に印象的であることを示し、1秒以上。まあ、それよりも速く、すべての回でParallel.Forされていませんか?もちろん、答えは「ノー」であるか、あるいはマイクロソフトのために維持もしているのですか?

ここでは、グローバル変数NUM、次のコードを追加するコードを変更します。

public void ParallelForMethod()
         {
            var obj = new Object();
            long num = 0;
            ConcurrentBag<long> bag = new ConcurrentBag<long>();

            stopWatch.Start();
            for (int i = 0; i < 10000; i++)
            {
               for (int j = 0; j < 60000; j++)
               {
                  //int sum = 0;
                  //sum += item;
                  num++;
               }
            }
            stopWatch.Stop();
            Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            Parallel.For(0, 10000, item =>
            {
               for (int j = 0; j < 60000; j++)
               {
                  //int sum = 0;
                  //sum += item;
                  lock (obj)
                  {
                     num++;
                  }
               }
            });
            stopWatch.Stop();
            Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

         }

Parallel.Forそれは並列で実行されているので、それはまた、ロックを使用するために、正しい結果を得るために、結果を見て、この時間をグローバル変数num個にアクセスします:
ここで説明する絵を書きます
ああ驚いていないのですか?Parallel.Forは実際にほとんどしばらく前にしてのために、15秒以上かかりました。これは、グローバル変数への並列同時アクセスが主な原因である、リソースの競合があるだろう、ほとんどの時間は、上記のリソースを待機中に消費しました。

パラレルは、あなたがそれをParallel.Forが並列に実行されているところからそれを見ることができる、と言われていますか?のは、テストコードを書いてみましょう:

Parallel.For(0, 100, i =>
            {
               Console.Write(i + "\t");
            });

配列が同時に並行して、肯定的であるため0〜99から出力され、動作は、順次出力を見つけることができません、異なる出力順が起こります。

3、Parallel.Foreach

この方法は、foreachの方法に非常に似て、特定の知識をしたい、あなたが百度でいくつかの情報を見ることができ、言っても過言では次の方法を使用することを考えると、そこではありません。

List<int> list = new List<int>();
            list.Add(0);
            Parallel.ForEach(list, item =>
            {
               DoWork(item);
            });

二、並列ループや例外処理のドロップアウト

私たちはパラレルために使用する場合1を、我々が途中で停止している場合、どのようにそれを行うには、当然のことながら、より多くの時間のかかる操作のいくつかに対処するためにCPUとメモリの無駄をバインドされていますか?

シリアルコードでは、我々は得るためにそれを破るが、パラレルはそれほど単純ではありませんが、それは大丈夫だ、並列サイクルでデリゲートパラメータParallelLoopStateを提供します

この例では、ブレークを提供し、Stopメソッドは、私たちが達成するために。

ブレイク:もちろん、このような並列コンピューティングとして、できるだけ早く、並列コンピューティングの出口にループを知らせるためであることは、反復100で、プログラムは100未満のすべての繰り返しの後に解除されます。

停止:このケースではありません、たとえば、あなたは突然、関係なく、それが何だったか、100回の反復を停止遭遇していない、と出ています。

のは、テストへのコードの一部を書いてみましょう:

public void ParallelBreak()
         {
            ConcurrentBag<int> bag = new ConcurrentBag<int>();
            stopWatch.Start();
            Parallel.For(0, 1000, (i, state) =>
            {
               if (bag.Count == 300)
               {
                  state.Stop();
                  return;
               }
               bag.Add(i);
            });
            stopWatch.Stop();
            Console.WriteLine("Bag count is " + bag.Count + ", " + stopWatch.ElapsedMilliseconds);
         }

ここで使用される数が300に達したとき、それはすぐに停止する、停止され、あなたが休憩が、結果は300人以上または300可能性がある場合、我々はテストすることができ、結果は「袋数は300である」を参照してくださいすることができます。

2、例外処理

  最初のタスクは、コンピューティングを平行している、プロセスが行うこれらの異常を取得する方法を、異常のn個の数を生成できますか?例外普通と異常に取得することはできませんが、並列AggregateExcepationの誕生は、あなたは、例外のセットに取得することができます。

ここでは、次のようにコードを修正し、Parallel.Invokeコードを変更します。

public class ParallelDemo
      {
         private Stopwatch stopWatch = new Stopwatch();

         public void Run1()
         {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
            throw new Exception("Exception in task 1");
         }
         public void Run2()
         {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
            throw new Exception("Exception in task 2");
         }

         public void ParallelInvokeMethod()
         {
            stopWatch.Start();
            try
            {
               Parallel.Invoke(Run1, Run2);
            }
            catch (AggregateException aex)
            {
               foreach (var ex in aex.InnerExceptions)
               {
                  Console.WriteLine(ex.Message);
               }
            }
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Reset();
            stopWatch.Start();
            try
            {
               Run1();
               Run2();
            }
            catch(Exception ex)
            {
               Console.WriteLine(ex.Message);
            }
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
         }
}

これが唯一の例外にRUN1の情報をキャッチすることができ、私が一緒に書かれた例外処理を置くために、メソッドを呼び出して、あなたは個別に書くことができます。AggregateException例外を捕捉した後、出力異常情報を介してforeachループと、異常情報は、2台のディスプレイを見ることができます。

より転載http://www.cnblogs.com/yunfeifei/p/3993401.html
ソースコードおよび詳細については、ビューをダウンロードして行くことができます

おすすめ

転載: blog.csdn.net/rui15111/article/details/78789627
おすすめ