Task 异常处理 线程取消 局部变量问题

来源:互联网 发布:欧文职业生涯数据 编辑:程序博客网 时间:2024/05/26 09:54

先来一个局部变量的问题 

如下面代码

 for (int i = 0; i < 10; i++)                {                    Task.Run(new Action(() => {                        Console.WriteLine(i);                    }));                }

看到上面代码 本以为 输出会是0-9  结果看下面


这是因为是异步,所以i++并没有等待Task.Run的执行,所以i在一直++下去 就变成了10 

可以用下面代码来解决上面问题

for (int i = 0; i < 10; i++)                {                    string value = i.ToString();                    Task.Run(new Action(() => {                        Console.WriteLine(value);                    }));                }

用一个新的局部变量来存上i的值 就可以实现输出正确的值了



异常处理

这里就不演示了,直接说明,对于多线程的异常处理,不能包在最外面,这样会抓不到异常,因为在还没有报异常的时候,主线程就已经执行完了,应该直接把Try catch紧紧的包裹着Task的外面

 for (int i = 0; i < 5; i++)                {                    string value = i.ToString();                    Task.Run(new Action(() =>                    {                        try                        {                            if (value == "3")                            {                                throw new Exception("错误");                            }                            Console.WriteLine("执行成功,线程ID为{0}", Thread.CurrentThread.ManagedThreadId);                        }                        catch (Exception)                        {                            Console.WriteLine("有一个执行失败");                            throw;                        }                    }));                }


线程取消
 CancellationTokenSource cts = new CancellationTokenSource(); 
for (int i = 0; i < 50; i++)                {                    string value = i.ToString();                    Task.Run(new Action(() =>                    {                        try                        {                            if (value == "3")                            {                                throw new Exception("错误");                            }                            Thread.Sleep(200);                          if (!cts.IsCancellationRequested)//IsCancellationRequested 被取消                          {                              Console.WriteLine("{0} 执行成功", Thread.CurrentThread.ManagedThreadId);                          }                          else                          {                              Console.WriteLine("{0} 被取消", Thread.CurrentThread.ManagedThreadId);                          }                        }                        catch (Exception)                        {                            cts.Cancel();                            Console.WriteLine("有一个执行失败");                            throw;                        }                    }));                }
注意:在上面代码中,StartNew来启动一个线程的时候。可以通过传递cts.Token参数的方式,来让线程执行前就判断是否已经取消
结果


0 0
原创粉丝点击