【发布时间】:2020-03-11 10:05:19
【问题描述】:
我在单独的线程中运行一些代码,这可能会引发异常(毕竟,代码往往会这样做)。该线程将从主线程 (GUI) 生成,因此最终必须在此处处理异常(例如设置错误消息文本块)。我有两种解决方案,但都不允许在 GUI 线程中直接捕获异常。
注意:我不能使用像 Task 和 BackgroundWorker (至少不是开箱即用)之类的东西,因为我需要能够更改线程的 ApartmentState 。
这是我想要的:
var thread = new Thread(() =>
{
// Code which can throw exceptions
});
try
{
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
MethodThatAwaitsThread(thread);
}
catch
{
// Exception handling in the GUI thread
}
这不起作用,因为异常永远不会离开线程。我知道它不能随时离开线程,但我可以等待线程结束,然后捕获它。
这是我当前的解决方案,它利用Dispatcher 与 GUI 线程对话:
var thread = new Thread(() =>
{
try
{
// Code which can throw exceptions
Dispatcher.Invoke(UpdateGuiAsSuccess);
}
catch (Exception ex)
{
Dispatcher.Invoke(UpdateGuiAsError);
}
}
另一种解决方案是将Exception 存储在一个对象中,然后显式检查它。但这会带来人们忘记检查异常的风险:
Exception ex = null;
var thread = new Thread(() =>
{
try
{
// Code which can throw exceptions
}
catch (Exception threadEx)
{
ex = threadEx;
}
}
if (ex != null)
{
UpdateGuiAsError();
}
else
{
UpdateGuiAsSuccess();
}
一旦工作线程死亡,我是否可以在 GUI 线程中重新抛出错误?
【问题讨论】:
-
我没有完全阅读它,但考虑到准备和细节,值得一票。这种令人耳目一新的变化 :) 你可能会觉得这很方便:stackoverflow.com/q/30326673/495455
-
另外,获取 VS 插件:单一调试模式
-
“我不能使用任务之类的东西”是错误的。你只是没有在 StackOverflow 上搜索
[c#] Task STA -
另一种解决方案(更详细但也更符合 TPL 起源的精神):ParallelExtensionsExtras Tour – #5 – StaTaskScheduler
标签: c# wpf multithreading