由于工作需要,需要自动执行一系列任务,任务里面有很多步骤,其内部的逻辑不可控,原本的任务为线程实现,未实现超时机制,因为一个任务的总体超时时间不好设定,但是一个步骤一般运行不超过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("线程二抛出异常"); } } }
于是我定义了一个全局变量_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("线程二抛出异常"); } } }