天天看點

并行線程代碼

  /// <summary>

    /// Parallel并行線程  

    /// </summary>

    public class Parallel1

    {

        public static Stopwatch sw = new Stopwatch();

        public List<int> list1 = new List<int>();

        public Dictionary<string, int> dic = new Dictionary<string, int>();

        #region 并行

        public void SetListOrDic()

        {

            sw.Stop();

            sw.Restart();

            for (int i = 0; i < 1000; i++)

            {

                list1.Add(i);

            }

            sw.Stop();

            Console.WriteLine("執行List的時間" + sw.Elapsed);

            sw.Restart();

            for (int i = 0; i < 1000; i++)

            {

                dic.Add("dic" + i, i);

            }

            sw.Stop();

            Console.WriteLine("執行dic的時間" + sw.Elapsed);

            sw.Restart();

            int s = 0;

            foreach (var item in list1)

            {

                s += item;

            }

            sw.Stop();

            Console.WriteLine("周遊list的時間" + sw.Elapsed + "結果為" + s);

            sw.Restart();

            int w = 0;

            foreach (var item in dic)

            {

                w += item.Value;

            }

            sw.Stop();

            Console.WriteLine("周遊dic的時間" + sw.Elapsed + "結果為" + w);

        }

        public static void Run1()

        {

            Thread.Sleep(2000);

            Console.WriteLine("阻塞2000");

        }

        public static void Run2()

        {

            Thread.Sleep(3000);

            Console.WriteLine("阻塞3000");

        }

        /// <summary>

        /// 列印并行執行操作

        /// </summary>

        public void Run1AndRun2()

        {

            sw.Start();

            Parallel.Invoke(Run1, Run2);//并行執行操作方法

            sw.Stop();

            Console.WriteLine("并行時間:" + sw.ElapsedMilliseconds);

            sw.Restart();

            Run1();

            Run2();

            sw.Stop();

            Console.WriteLine("run1+run2的時間" + sw.ElapsedMilliseconds);

        }

        /// <summary>

        /// 結束并行操作

        /// </summary>

        public void BreakOrStop()

        {

            ConcurrentBag<int> con = new ConcurrentBag<int>();//表示對線程安全的無序集合

            sw.Start();

            //使用stop

            Parallel.For(0, 1000, (i, state) =>

            {

                if (con.Count() == 300)

                {

                    state.Stop();

                    return;

                }

                con.Add(i);

            });

            sw.Stop();

            Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);

            sw.Restart();

            //使用break

            Parallel.For(0, 1000, (i, state) =>

            {

                if (con.Count() == 300)

                {

                    state.Break();

                    return;

                }

                con.Add(i);

            });

            sw.Stop();

            Console.WriteLine("集合數" + con.Count + "時間" + sw.ElapsedMilliseconds);

        }

        #endregion

    }

    /// <summary>

    /// 并行Linq

    /// </summary>

    public class ParallelLinq

    {

        Stopwatch sq = new Stopwatch();

        List<Custom> ListByCustom = new List<Custom>();

        public void Plinq()

        {

            try

            {

                for (int i = 0; i < 2000000; i++)

                {

                       ListByCustom.Add(new Custom { Adress = "adress" + i, Age = i, Name = "namne" + i });

                }

                #region AsParallel()表示 把目前查詢并行化

                sq.Start();

                var list = ListByCustom.Where(i => i.Age > 55).ToList();

                sq.Stop();

                Console.WriteLine("普通linq時間為" + sq.ElapsedMilliseconds);

                sq.Restart();

                sq.Start();

                //AsParallel()表示 把目前查詢并行化

                var list1 = ListByCustom.AsParallel().Where(i => i.Age > 55).ToList();

                sq.Stop();

                Console.WriteLine("并行Linq時間為" + sq.ElapsedMilliseconds);

                #endregion

                #region Group 與ToLookup

                sq.Restart();

                var listgroup = ListByCustom.GroupBy(i => i.Age).ToList();

                sq.Stop();

                Console.WriteLine("Group時間"+sq.ElapsedMilliseconds);

                sq.Restart();

                var listgroup1 = ListByCustom.ToLookup(i => i.Age).ToList();

                sq.Stop();

                Console.WriteLine("ToLookup時間" + sq.ElapsedMilliseconds);

                #endregion

            }

            catch (ArgumentNullException ex)

            {

                Console.WriteLine(ex);

                sq.Stop();

            }

        }

        /// <summary>

        /// 并行輔助類

        /// </summary>

        public class Custom

        {

            public string Name { get; set; }

            public int Age { get; set; }

            public string Adress { get; set; }

        }

    }

    /// <summary>

    /// Task任務,兩種建立方式

    /// var t1=new Task(()=>{直接new

    ///    

    /// });

    /// 

    /// var t2=Task.Factory.StartNew(()=>{工廠模式建立

    /// 

    /// });

    /// </summary>

    public class GetTask {

        public void GetTasks() {

            //第一種建立方式 必須手動start

            var t1 = new Task(() => {

                Console.WriteLine("開始t1");

                Thread.Sleep(1000);//阻塞1秒

                Console.WriteLine("task1");

            });

            t1.Start();//使用new方式建立時必須手動start

            ///Task.Wait()等待線程完成,Task.WaiitAll()等待所有線程完成

            ///

            t1.Wait();//等待目前線程完成才執行其他代碼

            //第二種方式直接開啟

            var t2 = Task.Factory.StartNew(() => {

                Console.WriteLine("開始t2");

                Thread.Sleep(2000);

                Console.WriteLine("task2");

            });

            var t3 = Task.Factory.StartNew(() => {

                Console.WriteLine("開始t3");

                Thread.Sleep(2000);

                Console.WriteLine("task3");

            });

            //等待所有的線程完成才執行其他代碼

            //Task.WaitAll(t2,t3);

            //等效的還有Task.WaitAny,表示任意線程執行完後才執行

            //ContinueWith自動執行

            Console.WriteLine("線程完成");

            var result = t1.ContinueWith(task => {

                Console.WriteLine("自動線程");

                return "this is result";

            });

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

            #region Task嵌套 TaskCreationOptions.AttachedToParent指定将任務附加到目前結構層次的父級 qt與pt對比

            var qt = Task.Factory.StartNew(() => {

                var qt1 = Task.Factory.StartNew(() => {

                    Thread.Sleep(1000);

                    Console.WriteLine("this is Child1");

                 });

                Console.WriteLine("parent task1");

            });

            qt.Wait();

            Console.WriteLine("目前操作主任務qt并不會等待子任務qt1執行完才列印此消息");

            var pt = Task.Factory.StartNew(() =>

            {

                var pt1 = Task.Factory.StartNew(() => {

                    Thread.Sleep(1000);

                    Console.WriteLine("this is Child2");

                },TaskCreationOptions.AttachedToParent);

                Console.WriteLine("parent Task2");

            });

            pt.Wait();

            Console.WriteLine("主任務等待子任務執行完才列印此消息,關鍵字的作用TaskCreationOptions.AttachedToParent");

            #endregion

            Console.WriteLine("----------------------------------------------------------------");

            #region Task嵌套例子

            //描述:

            //C1得到主任務傳回的1+2

            //C2得到主任務傳回的1+3

            //C1的子任務的到C1的結果加上4

            //最後,将任務合并,輸出結果

                var Ztsk = Task.Factory.StartNew<int>(() => {

                    Console.WriteLine("開始主任務");

                    return 1;

                });

                //等待主任務完成

                Console.WriteLine("結果"+Ztsk.Result);

                Ztsk.Wait();

                //任務C2

                var C2 = Task.Factory.StartNew<int>(() =>

                {

                    Console.WriteLine("開始任務C2");

                    return Ztsk.Result + 3;

                });

                Console.WriteLine("結果"+C2.Result);

            //任務C1

                var C1 = Task.Factory.StartNew<int>(() =>

                {

                    Console.WriteLine("開始任務C1");

                    return Ztsk.Result + 2;

                }).ContinueWith<int>(task => {

                    Console.WriteLine("開始任務C1的子任務");

                    return task.Result + 4;

                });

                Console.WriteLine("結果" + C1.Result);

            //等待所有任務完成

                Task.WaitAll(C1,C2);

            //列印結果

                Console.WriteLine("結果為"+(C2.Result+ C1.Result));

            #endregion

             Console.WriteLine("-----------------------------Task多線程問題 -----------------------------------");

        }

        #region Task多線程問題

        #region //死鎖例子

        public void TaskError()

        {var ts1 = Task.Factory.StartNew(() =>

            {

                Console.WriteLine("死鎖任務");

                while (true)

                {

                    Console.WriteLine("1");

                }

            });

            var ts2 = Task.Factory.StartNew(() =>

            {

                Console.WriteLine("Task 2");

                Thread.Sleep(1000);

                Console.WriteLine("結束任務");

            });

            Task.WaitAll(ts1, ts2);

 }

        #endregion

        #region   //解決死鎖,即設定最大等待時間,操過時間就退出

        public void RemoveSs() {

            Task[] task = new Task[2];

            task[0] = Task.Factory.StartNew(() => {

                Console.WriteLine("Task 1 Start running...");

                while (true)

                {

                    Thread.Sleep(3000);

                    Console.WriteLine("Task 1 Finished!");

                }

            });

            task[1] = Task.Factory.StartNew(() => {

                Console.WriteLine("Task 2 Start running...");

                System.Threading.Thread.Sleep(2000);

                Console.WriteLine("Task 2 Finished!");

            });

            //等待的最大時間 為5秒

            Task.WaitAll(task,5000);

            for (int i = 0; i < task.Length; i++)

            {

                if (task[i].Status!=TaskStatus.RanToCompletion)

                {

                    Console.WriteLine("任務{0}沒有執行完",task[i].Id);

                }

            }

        }

        #endregion

        #endregion

        #region 計算例子

        public void GetResult() {

            bool su = false;

            var t1 = Task.Factory.StartNew<int>(() => {

                Console.WriteLine("第一個數字");

                return 1;

            });

            t1.Wait();

            var t2 = Task.Factory.StartNew<int>(() =>

            {

                Console.WriteLine("開始計算");

                return 5;

            }).ContinueWith(state => {

                if ((t1.Result + state.Result) >= 6)

                    Console.WriteLine("大于");

                else

                {

                    Console.WriteLine("不大于");

                }

            });

        }

        #endregion

    }

繼續閱讀