1. 线程的异常处理

 我们经常会遇到一个场景,开启了多个线程,其中一个线程报错,导致整个程序崩溃。这并不是我们想要的,我需要的结果是,其中一个线程报错,默默的记录下,其它线程正常进行,保证程序整体可以走下来。

解决方案:给函数体加try-catch,只让报错线程异常,其它线程可以正常进行。

         private void button7_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Console.WriteLine("----------------- 八.线程的特殊处理 --------------------------");
Console.WriteLine("----------------- button7_Click 开始 主线程id为:{0} --------------------------", Thread.CurrentThread.ManagedThreadId);
try
{ TaskFactory taskFactory = new TaskFactory();
List<Task> taskList = new List<Task>(); #region 01-异常处理
{
for (int i = ; i < ; i++)
{
string name = string.Format("button_Click{0}", i);
Action<object> act = t =>
{
try
{
//模拟报错
if (t.ToString().Equals("button_Click2"))
{
throw new Exception(string.Format("{0} 执行失败", t));
}
Console.WriteLine("{0} 执行成功", t);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
};
Task task = taskFactory.StartNew(act, name);
taskList.Add(task);
}
//线程等待
Task.WaitAll(taskList.ToArray());
}
#endregion }
catch (AggregateException aes)
{
foreach (var item in aes.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
} watch.Stop();
Console.WriteLine("----------------- button7_Click 结束 主线程id为:{0} 总耗时:{1}--------------------------", Thread.CurrentThread.ManagedThreadId, watch.ElapsedMilliseconds); }

运行结果:

2.  线程的取消

线程不能主动取消,只能通过信号量的形式进行检查,接到取消指令后,后续的线程都将取消。

  {
//Task不能主动取消,只能通过信号量检查的方式
CancellationTokenSource cts = new CancellationTokenSource();
for (int i = ; i < ; i++)
{
string name = string.Format("button_Click{0}", i);
Action<object> act = t =>
{
try
{
Thread.Sleep();
//模拟报错
if (t.ToString().Equals("button_Click2"))
{
throw new Exception(string.Format("{0} 执行失败", t));
}
if (cts.IsCancellationRequested)
{
Console.WriteLine("{0} 放弃执行", t);
}
else
{
Console.WriteLine("{0} 执行成功", t);
}
}
catch (Exception ex)
{
cts.Cancel(); //凡是在 button_Click2 的执行线程后执行的,均被放弃了执行
Console.WriteLine(ex.Message);
}
};
Task task = taskFactory.StartNew(act, name, cts.Token);
taskList.Add(task);
}
//线程等待
Task.WaitAll(taskList.ToArray());
}

运行结果:

3.  多线程临时变量

  {
for (int i = ; i < ; i++)
{
int k = i;
Action act = () =>
{
Console.WriteLine(k); //0,1,2,3,4 不一定按照顺序
Console.WriteLine(i); //全为5
};
act.BeginInvoke(null, null);
}
}

4. 线程安全

 当多个线程同时操控一个全局变量时,需要加锁,来保证线程安全。其中锁变量为 私有的静态object变量。eg: private static object btnThreadCore_Click_Lock = new object();

                 {
for (int i = ; i < ; i++)
{
Task task = taskFactory.StartNew(() =>
{
//只有方法外的变量需要加锁
int k = ;
lock (btnThreadCore_Click_Lock)
{
this.TotalCount += ;
}
});
taskList.Add(task);
}
//线程等待
Task.WaitAll(taskList.ToArray());
//测试输出结果
Console.WriteLine(this.TotalCount); //当不加线程锁的时候,结果不一定是10000,加锁后,一定为10000
}

5. 委托的几种赋值形式

三个方法:TestThread()、TestThread2(string name)、TestThread(string name,string pwd)。

形式一:声明的委托参数和要赋值的函数参数意义对应

eg:    Action act1=TestThread ;

Action<string> act2=TestThread2;

Action<string,string> act3=TestThread3;

注意:这种形式,需要在委托被调用的时候将函数所需的参数值传递进去。

形式二: 声明无参数委托,但利用()=>进行将有参数的函数转换,可以直接将参数所需的值传递进去,委托调用的时候,将不需要再传递了。

eg:    Action act1=TestThread ;

Action act2=()=>TestThread2("测试参数1");

Action act3=()=>TestThread3("测试参数1","测试参数2");

注意:这种形式,实际上就是直接将函数体赋值给委托,但又把一个函数当做内容传递到了这个函数体内,实际上

    Action act2=()=>TestThread2("测试参数1");   等价于

            Action act2=()=>{

            TestThread2("测试参数1");

           }。

形式三: 直接将函数体赋值给委托,然后函数体中的内容为一个新的函数,这种形式,需要在委托被调用的时候将函数所需的参数值传递进去。

eg:           Action act1=TestThread ;

Action act2=t=>TestThread2(t);

Action act3=(m,n)=>TestThread3(m,n);

注意:这种形式,实际上就是直接将函数体赋值给委托,但又把一个函数当做内容传递到了这个函数体内,实际上

    Action act2=t=>TestThread2(t);   等价于

            Action act2=(t)=>{

            TestThread2("测试参数1");

           }。

.Net进阶系列(15)-异步多线程(线程的特殊处理和深究委托赋值)(被替换)的更多相关文章

  1. .Net进阶系列(11)-异步多线程(委托BeginInvoke)(被替换)

    一. BeginInvoke最后两个参数的含义 倒数第二个参数:指该线程执行完毕后的回调函数:倒数第一个参数:可以向回调函数中传递参数. 下面以一段代码说明: /// <summary> ...

  2. .Net进阶系列(10)-异步多线程综述(被替换)

    一. 综述 经过两个多个周的整理,异步多线程章节终于整理完成,如下图所示,主要从基本概念.委托的异步调用.Thread多线程.ThreadPool多线程.Task.Parallel并行计算.async ...

  3. .Net进阶系列(13)-异步多线程(Task和Parallel)(被替换)

    一. Task开启多线程的三种形式 1. 利用TaskFactory下的StartNew方法,向StartNew传递无参数的委托,或者是Action<object>委托. 2. 利用Tas ...

  4. .Net进阶系列(14)-异步多线程(async和await)(被替换)

    1.  方法名前只有async,但是方法中Task实例前没有await关键字,该方法和普通方法没有什么区别,但是会报一个警告. #region 情况一 /// <summary> /// ...

  5. .Net进阶系列(12)-异步多线程(Thread和ThreadPool)(被替换)

    一. Thread多线程   1. 两种使用方式 通过F12查看Thread后,发现有两类构造函数,ParameterizedThreadStart和ThreadStart,其中 ThreadStar ...

  6. python进阶(15)多线程与多进程效率测试

    前言 在Python中,计算密集型任务适用于多进程,IO密集型任务适用于多线程   正常来讲,多线程要比多进程效率更高,因为进程间的切换需要的资源和开销更大,而线程相对更小,但是我们使用的Python ...

  7. 【C#进阶系列】29 混合线程同步构造

    上一章讲了基元线程同步构造,而其它的线程同步构造都是基于这些基元线程同步构造的,并且一般都合并了用户模式和内核模式构造,我们称之为混合线程同步构造. 在没有线程竞争时,混合线程提供了基于用户模式构造所 ...

  8. SilkTest高级进阶系列9 – 异步执行命令

    我们常常会使用sys_execute函数执行一些外部的程序或者命令来做一些事情,但是由于sys_execute是一个同步的函数,它会等待执行的命令完成后才会返回.在大多数情况下,这个函数足够用了. 但 ...

  9. .NET进阶篇06-async异步、thread多线程1

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出.纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人 本篇先做一个概述,列明一些基本概 ...

随机推荐

  1. session存入redis

    Session信息入Redis Session简介 session,中文经常翻译为会话,其本来的含义是 指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一 ...

  2. [转]ubuntu中查找软件的安装位置

    原博客地址:http://www.cnblogs.com/zhuyatao/p/4060559.html ubuntu中的软件可通过图形界面的软件中心安装,也可以通过命令行apt-get instal ...

  3. mybatis 缓存(cache)的使用

    许多应用程序,为了提高性能而增加缓存, 特别是从数据库中获取的数据. 在默认情况下,mybatis 的一级缓存是默认开启的.类似于hibernate, 所谓一级缓存,也就是基于同一个sqlsessio ...

  4. 关于jQuery.when()用法的调研

    1.该方法在jQuery1.5开始被引入. 2.用法测试 a.var url1 = "/resource/ar/hometab/index_tab_games.json",     ...

  5. day25 上山练习 计算圆练习

    # 练习一:在终端输出如下信息 # 小明,10岁,男,上山去砍柴 # 小明,10岁,男,开车去东北 # 小明,10岁,男,最爱大保健 # 老李,90岁,男,上山去砍柴 # 老李,90岁,男,开车去东北 ...

  6. 洛谷P4035 [JSOI2008]球形空间产生器(高斯消元)

    洛谷题目传送门 球啊球 @xzz_233 qaq 高斯消元模板题,关键在于将已知条件转化为方程组. 可以发现题目要求的未知量有\(n\)个,题目却给了我们\(n+1\)个点的坐标,这其中必有玄机. 由 ...

  7. mysql中存储过程

    存储过程procedure 存储过程,其本质还是函数——但其规定:不能有返回值: 定义形式: 说明: 1,in:用于设定该变量是用来“接收实参数据”的,即“传入”:默认不写,就是in 2,out:用于 ...

  8. time_t和difftime

    在C++中,下面这段代码可以获取一段时间差. time_t t1 = time(NULL); Sleep(); time_t t2 = time(NULL); cout << diffti ...

  9. 洛谷P3230 比赛

    emmmmmm,这个之前讲课的原题居然出到比赛里了. 我怒肝2h+然后A了此题,结果还是被某高一巨佬吊打...... 题意:n个球队两两比赛,胜得3分,败得0分,平得1分. 现有一个总分表,求问可能的 ...

  10. 【洛谷P3224】永无乡 并查集+Splay启发式合并

    题目大意:给定 N 个点的图,点有点权,初始有一些无向边,现在有 Q 个询问,每个询问支持动态增加一条无向边连接两个不连通的点和查询第 X 个点所在的联通块中权值第 K 大的是哪个点. 题解:学会了平 ...