我有线程这样,在看到示例link text
之后ThreadStart _threadStart = new ThreadStart(delegate()
{
try
{
threadFunction(httpContext);
}
catch (Exception ex)
{
throw ex;
}
});
Thread _thread = new Thread(_threadStart);
_thread.Start();
当异常发生时,它不会在启动它的线程中重新抛出。 那么我做错了什么或怎么做?
注意:感谢先进的所有评论
答案 0 :(得分:7)
将抛出异常,但这只会结束线程。该异常不会在启动它的线程中重新抛出。
答案 1 :(得分:6)
我认为问题的核心是要理解线程中发生的异常不会传递给调用线程进行处理。
例如,假设您有反叛方法:
private static void RebelWithoutACause()
{
throw new NullReferenceException("Can't touch this!");
}
假设您创建了一个在程序中调用此方法的新线程,并且作为一名安全的程序员,您决定将工作包含在try/catch
块中:
private static void Main(string[] args)
{
try
{
var thread = new Thread(RebelWithoutACause);
thread.Start();
thread.Join();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
但是,如果你在调试器中运行它,你会发现你永远不会到达catch
块,而是线程将被杀死,调试器会抱怨你有一个未处理的异常。
您需要选择如何处理异常,但需要在每个线程入口方法中进行处理。典型处理包括记录详细信息,通过UI通知用户,以及尽可能优雅地关闭应用程序。
答案 2 :(得分:2)
你确定抛出了异常吗?如果一个线程因异常而失败,那么整个应用程序都会崩溃,您可以注意到AppDomain.CurrentDomain.UnhandledException事件(请注意,在事件触发时,您无法阻止您的应用程序被终止,但可以清除 - 增加资源并保存关键数据 - 有关详细信息,请参阅事件文档。
但是,引用您引用的主题中的accepted answer:
任何引发顶级异常的线程都表明存在很大问题。
您应该尝试记录异常,和/或发信号通知该线程失败的其他线程。
答案 3 :(得分:1)
抛出异常,除了我猜你没有看到它,因为它被抛出在另一个线程上。因此,UI线程(或任何调用其他线程的线程)无法捕获异常,因为它没有看到它。
例如,如果您将异常记录到文件中,我相信您会看到它。 :)
答案 4 :(得分:0)
我想也许您应该考虑使用BackgroundWorker类。您可以订阅RunWorkerCompleted事件,并且它具有包含您的例外的Error属性。
答案 5 :(得分:0)
也许会做这样的事情:
const int numThreads = 8;
Thread[] threads = new Thread[numThreads];
Exception[] threadsExceptions = new Exception[numThreads];
for (int i = 0; i < numThreads; i++) {
threadsExceptions[i] = null;
int closureVariableValue = i;
ThreadStart command = () =>
{
try
{
throw new ArgumentException("thread_" + closureVariableValue + "'s exception");
}catch(Exception any)
{
threadsExceptions[closureVariableValue] = any;
}
};
threads[i] = new Thread(command);
threads[i].Start();
}
for(int i = 0; i < numThreads; i++)
{
threads[i].Join();
if (threadsExceptions[i] != null)
{
throw threadsExceptions[i];
}
}