码迷,mamicode.com
首页 > Windows程序 > 详细

(C#) Tasks 中的异常处理(Exception Handling.)

时间:2015-12-27 23:20:46      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:

多线程编程中要注意对线程异常的处理。首先写个例子。

一个线程用于显示信息(Show Messages)。主线程用于做其他工作(Do Works)。

            using (Task taskShowMessages = new Task(ShowMessages))
            {
                try
                {
                    taskShowMessages.Start();
                    DoWorks();
                }
                catch (DoWorkException ex)
                {
                    Console.WriteLine("Error:{0}", ex.Message);
                }
                catch(Exception ex)
                {
                    Console.WriteLine("Error:{0}", ex.Message); 
                }
            }
 public static void ShowMessages()
        {
            int i = 0; 
            while (true)
            {
                Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++);
                Thread.Sleep(1000); 

                if ( i == 3)
                {
                    throw new ShowMessageException(string.Format("User defined error occured during showing message_{0}!", i));
                    //throw new Exception(string.Format("Unhandled exception occured during showing message_{0}!", i)); 
                }
            }
        }

        public static void DoWorks()
        {
            int i = 0;
            while (true)
            {
                Console.WriteLine("{0} - DoWork_{1}", DateTime.Now.ToString(), i++);
                Thread.Sleep(2000);

                if (i == 4)
                {
                    throw new DoWorkException(string.Format("User defined error occured during doing work_{0}!", i));
                    //throw new Exception(string.Format("Unhandled exception occured during doing work{0}!", i)); 
                }
            }
        }

        public class ShowMessageException : Exception
        {
            public ShowMessageException(String message)
                : base(message)
            {
            }
        }

         public class DoWorkException : Exception
        {
             public DoWorkException(String message)
                : base(message)
             {
             }
        }

输出:

12/27/2015 10:08:03 PM - DoWork_0
12/27/2015 10:08:03 PM - Message_0
12/27/2015 10:08:04 PM - Message_1
12/27/2015 10:08:05 PM - DoWork_1
12/27/2015 10:08:05 PM - Message_2
12/27/2015 10:08:07 PM - DoWork_2
12/27/2015 10:08:09 PM - DoWork_3
Error:User defined error occured during doing work_4!


可以看出来,Show Message 3 时发生一个异常,但是本程序无视它并继续DoWorks。知道DoWorks发生异常抛出。
在VS的debug环境下可以看到这个异常的发生:

A first chance exception of type ConsoleApplication2.Program.ShowMessageException occurred in ConsoleApplication2.exe
A first chance exception of type ConsoleApplication2.Program.DoWorkException occurred in ConsoleApplication2.exe


如果想正确的处理ShowMessage线程的异常,必须对其 Wait()方法进行处理。

            using (Task taskShowMessages = new Task(ShowMessages))
            {
                try
                {
                    taskShowMessages.Start();
                    DoWorks();
                }
                catch (DoWorkException ex)
                {
                    Console.WriteLine("Error is handled:{0}", ex.Message);
                }
                finally
                {
                    try
                    {
                        taskShowMessages.Wait(); 
                    }
                    catch(AggregateException ae)
                    {
                        ae.Handle((x) =>
                            {
                                if (x is ShowMessageException)
                                {
                                    Console.WriteLine("Error is handled:{0}", x.Message);
                                    return true; 
                                }
                                else
                                {
                                    return false; 
                                }
                            }); 
                    }
                }
            }

 

输出:

12/27/2015 10:16:37 PM - DoWork_0
12/27/2015 10:16:37 PM - Message_0
12/27/2015 10:16:38 PM - Message_1
12/27/2015 10:16:39 PM - DoWork_1
12/27/2015 10:16:39 PM - Message_2
12/27/2015 10:16:41 PM - DoWork_2
12/27/2015 10:16:43 PM - DoWork_3
Error is handled:User defined error occured during doing work_4!
Error is handled:User defined error occured during showing message_3!

 

那么现在如果其中一个线程出现异常的话,我们就希望抛出异常,结束程序,怎么做?

答案就是使用:

CancellationTokenSource

        static CancellationTokenSource cancellationtoken = new CancellationTokenSource();
        static void Main(string[] args)
        {

            using (Task taskShowMessages = new Task(ShowMessages, cancellationtoken.Token))
            {
                try
                {
                    taskShowMessages.Start();
                    DoWorks();
                }
                catch (DoWorkException ex)
                {
                    Console.WriteLine("Error is handled:{0}", ex.Message);
                }
                finally
                {
                    cancellationtoken.Cancel();

                    try
                    {
                        taskShowMessages.Wait();
                    }
                    catch (AggregateException ae)
                    {
                        ae.Handle((x) =>
                            {
                                if (x is ShowMessageException)
                                {
                                    Console.WriteLine("Error is handled:{0}", x.Message);
                                    return true;
                                }
                                else
                                {
                                    return false;
                                }
                            });
                    }
                }
            }
        }

        public static void ShowMessages()
        {
            int i = 0;
            while (!cancellationtoken.IsCancellationRequested)
            {
                Console.WriteLine("{0} - Message_{1}", DateTime.Now.ToString(), i++);
                Thread.Sleep(1000); 

                if ( i == 3)
                {
                    //throw new ShowMessageException(string.Format("User defined error occured during showing message_{0}!", i));
                    //throw new Exception(string.Format("Unhandled exception occured during showing message_{0}!", i)); 
                    //break; 
                }
            }
        }

 

输出:

12/27/2015 10:40:56 PM - DoWork_0
12/27/2015 10:40:56 PM - Message_0
12/27/2015 10:40:57 PM - Message_1
12/27/2015 10:40:58 PM - DoWork_1
12/27/2015 10:40:58 PM - Message_2
12/27/2015 10:40:59 PM - Message_3
12/27/2015 10:41:00 PM - DoWork_2
12/27/2015 10:41:00 PM - Message_4
12/27/2015 10:41:01 PM - Message_5
12/27/2015 10:41:02 PM - DoWork_3
12/27/2015 10:41:02 PM - Message_6
12/27/2015 10:41:03 PM - Message_7
Error is handled:User defined error occured during doing work_4!

 

 

 

 

参考:

https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/dd537614(v=vs.110).aspx

 

(C#) Tasks 中的异常处理(Exception Handling.)

标签:

原文地址:http://www.cnblogs.com/fdyang/p/5081058.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!