Parallel,Task


  Parallel.Invoke(Run1, Run2);  //  儘可能並行執行提供的每個操作。
//執行 for(在 Visual Basic 中爲 For)循環,其中可能會並行運行迭代。
            Object obj = new object();
            int num = 0;
            Parallel.For(0, 1000, i =>
            {
                int sum = 0;
                for (int j = 0; j < 1000; j++)
                {
                    sum += j;
                    //Parallel.For由於是並行運行的,所以會同時訪問全局變量num,爲了得到正確的結果,要使用lock;
                    //    這時並行會很慢,這主要是由於並行同時訪問全局變量,會出現資源爭奪,大多數時間消耗在了資源等待上面。
                        lock (obj)
                    {
                        num++;
                    }
                }
            });
            //數據小或者要訪問全局變量時不推薦使用; Parallel.ForEach用法類似

中途退出並行循環

 ConcurrentBag<int> bag = new ConcurrentBag<int>();
 Random rdm = new Random();
 Parallel.For(0, 1000, (i, state) =>
            {
               Thread.Sleep(rdm.Next(10, 100));
                if (bag.Count == 300)
                {
                    state.Stop();
              //  state.Break();
                    return;
                }
                bag.Add(i);
            });

並行的異常捕獲

        public void Run1()
        {
            Thread.Sleep(1000);
            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");
        }

        try
        {
            Parallel.Invoke(Run2, Run1);
        }
        catch (AggregateException aex)
        {
            foreach (var ex in aex.InnerExceptions)
            {
                Console.WriteLine(ex.Message);
            }
        }
            //如果用Exception也能捕獲到,但是得轉成AggregateException才能點出InnerExceptions獲取異常的具體信息,不然ex.Message的信息是"一個或多個異常"

指定使用的硬件線程數

            var bag = new ConcurrentBag<int>();

            ParallelOptions options = new ParallelOptions();          
            //指定使用的硬件線程數
            options.MaxDegreeOfParallelism = Environment.ProcessorCount-1;

            stopWatch.Restart();
            Parallel.For(0, 9000000, options, i =>
            {
                bag.Add(i);
            });
            stopWatch.Stop();
            Console.WriteLine("並行計算:集合有:{0}", bag.Count + ", " + stopWatch.ElapsedMilliseconds);
            Console.ReadKey();

Task

Wait

 var task1 = new Task(() =>
            {
                Console.WriteLine("Task 1 Begin");
                System.Threading.Thread.Sleep(2000);
                Console.WriteLine("Task 1 Finish");
            });

            var task2 = new Task(() =>
            {
                Console.WriteLine("Task 2 Begin");
                System.Threading.Thread.Sleep(5000);
                Console.WriteLine("Task 2 Finish");
            });

            Console.WriteLine("Before start:" + task1.Status);
            task1.Start();
            task2.Start();
            Console.WriteLine("After start:" + task1.Status);
            task1.Wait(); //等待Task1完成了纔會往下走
            Console.WriteLine("After Finish:" + task1.Status);

            Task.WaitAny(task1, task2); //等待Task1Task2任意一個完成了纔會往下走
            Task.WaitAll(task1, task2); //等待Task1Task2都完成了纔會往下走

            Console.WriteLine("All task finished!");

            Console.ReadKey();

ContinueWith

   var task1 = new Task(() =>
            {
                Console.WriteLine("Task 1 Begin");
                Thread.Sleep(2000);
                Console.WriteLine("Task 1 Finish");
            });

            var task2 = new Task(() =>
            {
                Console.WriteLine("Task 2 Begin");
                Thread.Sleep(3000);
                Console.WriteLine("Task 2 Finish");
            });

            task1.Start();
            task2.Start();
            var result = task1.ContinueWith<string>(task =>
            {
                Console.WriteLine("task1 finished!");
                return "This is task result!";
            });

            Console.WriteLine(result.Result.ToString());
            Console.ReadKey();

            ///在每次調用ContinueWith方法時,每次會把上次Task的引用傳入進來,以便檢測上次Task的狀態,比如我們可以使用上次TaskResult屬性來獲取返回值。
            var SendFeedBackTask = Task.Factory.StartNew(() => { Console.WriteLine("Get some Data!"); })
                                .ContinueWith<bool>(s => { return true; })
                                .ContinueWith<string>(r =>
                                {
                                    if (r.Result)
                                    {
                                        return "Finished";
                                    }
                                    else
                                    {
                                        return "Error";
                                    }
                                });
            Console.WriteLine(SendFeedBackTask.Result);
            Console.ReadKey();

取消任務

            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            var task = Task.Factory.StartNew(() =>
            {
                for (var i = 0; i < 1000; i++)
                {
                    Thread.Sleep(100);
                    Console.WriteLine("Abort mission !");
                    if (token.IsCancellationRequested)
                    {
                        Console.WriteLine("Abort mission success!");
                        return;
                    }
                }
            }, token);
            token.Register(() =>
            {
                Console.WriteLine("Canceled");
            });

            Console.ReadKey();
            Console.WriteLine("Press enter to cancel task...");
            tokenSource.Cancel();
            Console.ReadKey();

屏障同步:使多個任務能夠採用並行方式在多個階段中協同工作

public static void Barrier()
        {
            Task[] tasks = new Task[4];

            Barrier barrier = null;
            //表示tasks.Lengt個Task到達屏障纔可以繼續執行
            barrier = new Barrier(tasks.Length, (i) =>
 {
     Console.WriteLine("**********************************************************");
     Console.WriteLine("\n屏障中當前階段編號:{0}\n", i.CurrentPhaseNumber);
     Console.WriteLine("**********************************************************");

 });

            for (int j = 0; j < tasks.Length; j++)
            {
                tasks[j] = Task.Factory.StartNew((obj) =>
                {
                    var single = Convert.ToInt32(obj);

                    LoadUser(single);
                    barrier.SignalAndWait(); //發出參與者已達到屏障並等待所有其他參與者也達到屏障。

                    LoadUser(single);
                    barrier.SignalAndWait();

                    LoadProduct(single);
                    barrier.SignalAndWait();

                    LoadOrder(single);
                    barrier.SignalAndWait();
                }, j);
            }
            Console.ReadKey();
        }


        static void LoadUser(int num)
        {
            Console.WriteLine("當前任務:{0}正在加載User部分數據!", num);
        }

        static void LoadProduct(int num)
        {
            Console.WriteLine("當前任務:{0}正在加載Product部分數據!", num);
        }

        static void LoadOrder(int num)
        {
            Console.WriteLine("當前任務:{0}正在加載Order部分數據!", num);
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章