线程通知另一个例外的thead

ThreadA生成ThreadB。

ThreadB抛出exception。

ThreadA如何知道这个exception?

using System; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ThreadStart threadDelegate1 = new ThreadStart(MyClass1.DoThis); Thread ThreadA = new Thread(threadDelegate1); ThreadA.Start(); Thread.Sleep(100000); // this thread is doing something else here, sleep simulates it } } class MyClass1 { public static void DoThis() { try { ThreadStart threadDelegate1 = new ThreadStart(MyClass2.DoThat); Thread ThreadB = new Thread(threadDelegate1); ThreadB.Start(); Thread.Sleep(100000); // this thread is doing something else here, sleep simulates it } catch (Exception e) { // I want to know if something went wrong with MyClass2.DoThat } } } class MyClass2 { public static void DoThat() { throw new Exception("From DoThat"); } } } 

这是一种方法,使用ManualResetEvent和lambdas:

  try { Exception exc; using (ManualResetEvent resetEvent = new ManualResetEvent(false)) { Thread ThreadB = new Thread(() => { try { MyClass2.DoThat(); } catch (Exception e) { exc = e; resetEvent.Set(); } }); ThreadB.Start(); if (resetEvent.WaitOne(10000)) { throw exc; } } } catch (Exception e) { // I want to know if something went wrong with MyClass2.DoThat } 

您可以清理它,当然取决于您想要具体做什么。

只要您的线程处于hibernate状态,它就不会被另一个线程引起的exception中断。 如果你可以控制你的线程如何做其他事情,他应该在一个可警告的模式下等待,例如等待一个threadExceptionEvent。 如果你没有控制你的线程如何等待,你可以做的最好的事情就是检查线程之间的时间,例如boolexception标志并抛出这个。

以下代码显示了如何一次等待多个WaitHandles并根据触发的事件做出相应的反应。

 using System; using System.Threading; class Program { static AutoResetEvent _ExceptionEvent = new AutoResetEvent(false); static WaitHandle _SomeEvent = new AutoResetEvent(false); static WaitHandle[] _Waiters = new WaitHandle[] { _ExceptionEvent, _SomeEvent }; static Exception _LastThrownException = null; static int _CatchedExCount = 0; static void ThreadA() { while (true) { int eventIdx = WaitHandle.WaitAny(_Waiters); if (eventIdx == 0) // Exception event { Exception lastEx = Interlocked.Exchange(ref _LastThrownException, null); if (lastEx != null) { Console.WriteLine("Thread A got exception {0}", lastEx.Message); _CatchedExCount++; //throw lastEx; } } } } static void ThreadB() { while (true) { try { ThreadBWorker(); } catch (Exception ex) { // Do not overwrite a pending exception until it was processed Exception old = null; do { old = Interlocked.CompareExchange(ref _LastThrownException, ex, null); if( old != null) // wait a bit to allow processing of existing exception { Thread.Sleep(1); } } while (old != null); _ExceptionEvent.Set(); } } } static int _exCount = 0; static void ThreadBWorker() { throw new Exception("Thread B Exception " + _exCount++); } static void Main(string[] args) { Thread t2 = new Thread(ThreadB); t2.Start(); // start producing exception Thread t1 = new Thread(ThreadA); t1.Start(); // wait for exceptions } } 

你的,Alois Kraus