子线程异常处理

由于工作需要,需要自动执行一系列任务,任务里面有很多步骤,其内部的逻辑不可控,原本的任务为线程实现,未实现超时机制,因为一个任务的总体超时时间不好设定,但是一个步骤一般运行不超过10分钟,任务执行失败会抛异常给任务执行线程,代表执行出错,但是这里有一个问题,步骤如果执行长时任务有可能会因为某种原因一直等待,所以不但任务要线程实现,步骤也要线程实现,并且实现步骤线程捕获了异常抛给任务线程

大致结构如下:

任务1

  步骤1

  步骤2

  ……

任务2

任务3

……

  

下方是个简单的Demo,线程一模拟任务线程,线程二模拟步骤线程,实现的时候遇到了麻烦,捕获异常时线程二方法内部并没有跑抛异常给线程一去处理,而是因为未捕获异常直接终止了程序

using System;
using System.Threading;

namespace SubThreadException
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var thread1 = new Thread(ThreadOne) { Name = "" };
                thread1.Start();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private static void ThreadOne()
        {
            Thread.Sleep(3000);
            Console.WriteLine("我是线程一方法,我启动线程二");
            try
            {
                var thread2 = new Thread(() =>
                    {
                        try
                        {
                            ThreadTwo();
                        }
                        catch (Exception)
                        {
                            throw;
                        }

                    }) { Name = "" };
                thread2.Start();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private static void ThreadTwo()
        {
            Thread.Sleep(3000);
            Console.WriteLine("我是线程二方法");
            throw new Exception("线程二抛出异常");
        }
    }
}
View Code

 于是我定义了一个全局变量_exception, 或许方法比较菜,但是很好的解决了底层抛异常给上层的问题

using System;
using System.Threading;

namespace SubThreadException
{
    class Program
    {
        private static Exception _exception;
        static void Main(string[] args)
        {
                var thread1 = new Thread(ThreadOne) { Name = "" };
                thread1.Start();
        }

        private static void ThreadOne()
        {
            _exception = null;
            Thread.Sleep(3000);
            Console.WriteLine("我是线程一方法,我启动线程二");
            try
            {
                var thread2 = new Thread(() =>
                    {
                        try
                        {
                            ThreadTwo();
                        }
                        catch (Exception e)
                        {
                            _exception = e;
                        }

                    }) { Name = "" };
                thread2.Start();
                if (!thread2.Join(20000))
                {
                    thread2.Abort();
                    throw new TimeoutException("我运行超过了20s");
                }
                if (_exception != null) throw _exception;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                Console.ReadKey();
            }

        }

        private static void ThreadTwo()
        {
            Thread.Sleep(10000);
            Console.WriteLine("我是线程二方法");
            throw new Exception("线程二抛出异常");
        }
    }
}
原文地址:https://www.cnblogs.com/haorui/p/3614824.html