2020年9月2日星期三

.NET异步和多线程系列(四)

本系列将和大家分享.Net中的异步和多线程,本文主要介绍的是多线程异常处理、线程取消、多线程的临时变量问题、线程安全和锁lock等。

本文是.NET异步和多线程系列第四章,主要介绍的是多线程异常处理、线程取消、多线程的临时变量问题、线程安全和锁lock等。

一、多线程异常处理

多线程里面抛出的异常,会终结当前线程,但是不会影响别的线程。那线程异常哪里去了? 被吞了。

假如想获取异常信息,这时候要怎么办呢?下面来看下其中的一种写法(不推荐):

/// <summary>/// 1 多线程异常处理和线程取消/// 2 多线程的临时变量/// 3 线程安全和锁lock/// </summary>private void btnThreadCore_Click(object sender, EventArgs e){ Console.WriteLine($"****************btnThreadCore_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +  $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************"); #region 多线程异常处理 {  try  {   List<Task> taskList = new List<Task>();   for (int i = 0; i < 100; i++)   {    string name = $"btnThreadCore_Click_{i}";    taskList.Add(Task.Run(() =>    {     if (name.Equals("btnThreadCore_Click_11"))     {      throw new Exception("btnThreadCore_Click_11异常");     }     else if (name.Equals("btnThreadCore_Click_12"))     {      throw new Exception("btnThreadCore_Click_12异常");     }     else if (name.Equals("btnThreadCore_Click_38"))     {      throw new Exception("btnThreadCore_Click_38异常");     }     Console.WriteLine($"This is {name}成功 ThreadId={Thread.CurrentThread.ManagedThreadId.ToString("00")}");    }));   }   //多线程里面抛出的异常,会终结当前线程,但是不会影响别的线程。   //那线程异常哪里去了? 被吞了。   //假如我想获取异常信息,还需要通知别的线程   Task.WaitAll(taskList.ToArray()); //1 可以捕获到线程的异常  }  catch (AggregateException aex) //2 需要try-catch-AggregateException  {   foreach (var exception in aex.InnerExceptions)   {    Console.WriteLine(exception.Message);   }  }  catch (Exception ex) //可以多catch 先具体再全部  {   Console.WriteLine(ex);  }  //线程异常后经常是需要通知别的线程,而不是等到WaitAll,问题就是要线程取消?  //工作中常规建议:多线程的委托里面不允许异常,包一层try-catch,然后记录下来异常信息,完成需要的操作。 } 

没有评论:

发表评论