zoukankan      html  css  js  c++  java
  • Parallel 并行编程

    Parallel==Task+waitall(将主线程也利用了起来,改进了Task)
    Invoke()
    Parallel.Invoke(() =>
    this.DoSomethingLong("btnParallel_Click_0")
     , () => this.DoSomethingLong("btnParallel_Click_1")
     , () => this.DoSomethingLong("btnParallel_Click_2")
     , () => this.DoSomethingLong("btnParallel_Click_3")
     , () => this.DoSomethingLong("btnParallel_Click_4")
     , () => this.DoSomethingLong("btnParallel_Click_5"));

    For()

    1 Parallel.For(0, 5, t => this.DoSomethingLong($"btnParallel_Click_{t}"));

    Foreach()  (可以利用ParallelOptions设置最大并发数)

    1 Parallel.ForEach(new int[] { 1, 2, 3, 4, 5 }, t => this.DoSomethingLong($"btnParallel_Click_{t}"));
    1 ParallelOptions option = new ParallelOptions()
    2 {
    3     MaxDegreeOfParallelism = 3//最大并发数
    4 };
    5 Parallel.ForEach(new int[] { 1, 2, 3, 4, 5, 6 }, option, t =>
    6 {
    7     this.DoSomethingLong($"btnParallel_Click_{t}");
    8 });
     1 new Action(() =>
     2 {
     3 ParallelOptions option = new ParallelOptions()
     4 {
     5     MaxDegreeOfParallelism = 3//最大并发数
     6 };
     7 Parallel.ForEach(new int[] { 1, 2, 3, 4, 5, 6 }, option, t =>
     8 {
     9     this.DoSomethingLong($"btnParallel_Click_{t}");
    10 });
    11 }).BeginInvoke(null, null);
    线程嵌套线程

    结束线程 Break和Stop

     1 ParallelOptions option = new ParallelOptions()
     2 {
     3     MaxDegreeOfParallelism = 3//最大并发数
     4 };
     5 Parallel.ForEach(new int[] { 1, 2, 3, 4, 5, 6 }, option, (t, state) =>
     6 {
     7     this.DoSomethingLong($"btnParallel_Click_{t}");
     8     //state.Break();//这一次结束
     9     //return;
    10 
    11     state.Stop();//整个Parallel结束
    12     return;
    13     //不能共存
    14 });

    多线程的异常处理(主线程抓不到子线程的异常)

    1                 异常被吞掉了,加上waitall才能抓取到异常
    2                 Task.WaitAll(taskList.ToArray());

    (主线程)红色字体处捕获异常,但是异常已经发生(主线程抓不到子线程的异常)且其他的子线程已经执行(亡羊补牢,为时已晚)。所以,最好在子线程处处理异常,加上Task.WaitAll()。

      1 try
      2             {
      3                 TaskFactory taskFactory = new TaskFactory();
      4                 List<Task> taskList = new List<Task>();
      5                 #region 异常处理
      6                 ////在线程Action加上try catch,日志记录,不抛异常
      7                 //for (int i = 0; i < 20; i++)
      8                 //{
      9                 //    string name = string.Format($"btnThreadCore_Click_{i}");
     10                 //    Action<object> act = t =>
     11                 //    {
     12                 //        try//---------------------------------------------------------------子线程处理异常
     13                 //        {
     14                 //            Thread.Sleep(2000);
     15                 //            if (t.ToString().Equals("btnThreadCore_Click_11"))
     16                 //            {
     17                 //                throw new Exception(string.Format($"{t} 执行失败"));
     18                 //            }
     19                 //            if (t.ToString().Equals("btnThreadCore_Click_12"))
     20                 //            {
     21                 //                throw new Exception(string.Format($"{t} 执行失败"));
     22                 //            }
     23                 //            Console.WriteLine("{0} 执行成功", t);
     24                 //        }
     25                 //        catch (Exception ex)
     26                 //        {
     27                 //            Console.WriteLine(ex.Message);
     28                 //        }//-----------------------------------------------------------------子线程处理异常
     29                 //    };
     30                 //    taskList.Add(taskFactory.StartNew(act, name));
     31                 //}
     32                 ////异常被吞掉了,加上waitall才能抓取到异常
     33                 ////Task.WaitAll(taskList.ToArray());
     34                 #endregion
     35 
     36                 #region 线程取消
     37                 ////线程间都是通过共有变量:都能访问局部变量/全局变量/数据库的一个值/硬盘文件
     38                 ////线程不能被外部停止,只能自身停止自身;或者在任务启动前停止,会抛出异常的
     39                 //CancellationTokenSource cts = new CancellationTokenSource();
     40                 //for (int i = 0; i < 40; i++)
     41                 //{
     42                 //    string name = string.Format("btnThreadCore_Click{0}", i);
     43                 //    Action<object> act = t =>
     44                 //    {
     45                 //        try
     46                 //        {
     47                 //            //if (cts.IsCancellationRequested)
     48                 //            //{
     49                 //            //    Console.WriteLine("{0} 取消一个任务的执行", t);
     50                 //            //}
     51                 //            Thread.Sleep(2000);
     52                 //            if (t.ToString().Equals("btnThreadCore_Click11"))
     53                 //            {
     54                 //                throw new Exception(string.Format("{0} 执行失败", t));
     55                 //            }
     56                 //            if (t.ToString().Equals("btnThreadCore_Click12"))
     57                 //            {
     58                 //                throw new Exception(string.Format("{0} 执行失败", t));
     59                 //            }
     60                 //            if (cts.IsCancellationRequested)//检查信号量
     61                 //            {
     62                 //                Console.WriteLine("{0} 放弃执行", t);
     63                 //            }
     64                 //            else
     65                 //            {
     66                 //                Console.WriteLine("{0} 执行成功", t);
     67                 //            }
     68                 //        }
     69                 //        catch (Exception ex)
     70                 //        {
     71                 //            cts.Cancel();//表示修改了信号量  让大家取消执行
     72                 //            Console.WriteLine(ex.Message);
     73                 //        }
     74                 //    };
     75                 //    taskList.Add(taskFactory.StartNew(act, name, cts.Token));//没有启动的任务  在Cancel后放弃启动
     76                 //}
     77                 //Task.WaitAll(taskList.ToArray());
     78                 #endregion
     79 
     80                 #region 多线程临时变量
     81                 //for (int i = 0; i < 5; i++)
     82                 //{
     83                 //    int k = i;
     84                 //    new Action(() =>
     85                 //    {
     86                 //        Thread.Sleep(100);
     87                 //        //Console.WriteLine(i);
     88                 //        Console.WriteLine(k);
     89                 //    }).BeginInvoke(null, null);
     90                 //}
     91                 #endregion
     92 
     93                 #region 线程安全 lock
     94                 //共有变量:都能访问局部变量/全局变量/数据库的一个值/硬盘文件
     95                 for (int i = 0; i < 10000; i++)
     96                 {
     97                     int newI = i;
     98                     taskList.Add(taskFactory.StartNew(() =>
     99                     {
    100                         lock (btnThreadCore_Click_Lock)//lock后的方法块,任意时刻只有一个线程可以进入
    101                         {//这里就是单线程
    102                             this.TotalCount += 1;
    103                             IntList.Add(newI);
    104                         }
    105                     }));
    106                 }
    107                 Task.WaitAll(taskList.ToArray());
    108 
    109                 Console.WriteLine(this.TotalCount);
    110                 Console.WriteLine(IntList.Count());
    111                 #endregion
    112             }
    113             catch (AggregateException aex)//-------------------------------------------主线程捕获异常
    114             {
    115                 foreach (var item in aex.InnerExceptions)
    116                 {
    117                     Console.WriteLine(item.Message);
    118                 }
    119             }
    120             catch (Exception ex)
    121             {
    122                 Console.WriteLine(ex.Message);
    123             }
  • 相关阅读:
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    C++11六大函数(构造函数,移动构造函数,移动赋值操作符,复制构造函数,赋值操作符,析构函数)
    C++中virtual继承的深入理解
  • 原文地址:https://www.cnblogs.com/anwser-jungle/p/8881655.html
Copyright © 2011-2022 走看看