ThreadA生成ThreadB。
ThreadB抛出异常。
ThreadA如何知道此异常?
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");
}
}
}
答案 0 :(得分:0)
这是一种方法,使用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
}
你可以清理它,当然取决于你想要做什么。
答案 1 :(得分:0)
只要您的线程处于休眠状态,它就不会被另一个线程引起的异常中断。如果你可以控制你的线程如何做其他事情,他应该在一个可警告的模式下等待,例如等待threadExceptionEvent。 如果你没有控制你的线程如何等待,你可以做的最好的事情是检查你的线程之间的时间做了什么,例如一个bool异常标志并扔掉这个。
以下代码显示了如何一次等待多个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