並行線程代碼

  /// <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多線程問題
        /* 1,死鎖
              如果我們在調用Task.WaitAll方法等待所有線程時
           * ,如果有一個Task一直不返回,會出現什麼情況呢?
           * 當然,如果我們不做出來的話,程序會一直等待下去,
           * 那麼因爲這一個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


    }
發佈了45 篇原創文章 · 獲贊 41 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章