我有一个eventhandler,它给我一个异常作为参数。我想在UI线程上抛出该参数。看来这有时不会在UI线程上抛出异常,任何想法为什么?
_dispatcher = Application.Current.Dispatcher
if (_dispatcher != null && !_dispatcher.CheckAccess())
{
_dispatcher.BeginInvoke((ThreadStart)delegate
{
throw args.Exception;
}, DispatcherPriority.Normal);
return;
}
答案 0 :(得分:0)
我不确定您在何处或如何处理此事件,但有时您可能已经在UI线程上了吗?在那种情况下,你错过了另一半。
if (_dispatcher != null)
{
if (!_dispatcher.CheckAccess())
{
//invoke as above
}
else
{
throw args.Exception;
}
}
编辑:那就是说,我同意汉斯的观点。如果你向UI线程发送一个异常,谁会抓住它呢?
答案 1 :(得分:0)
看起来这有时不会在UI线程上抛出异常,任何想法为什么?
因此:
if (_dispatcher != null && !_dispatcher.CheckAccess())
您不需要CheckAccess()。
答案 2 :(得分:0)
你的问题很模糊,但看起来我最近遇到的问题。出于某些原因,当我从工作线程中捕获异常并尝试将其重新抛出到UI线程时,未处理异常(尽管有DispatcherUnhandledException
事件的子位置的高级错误管理)并且我的应用程序崩溃了。
这是我的原始代码
try
{
action(); // Perform task from worker thread
}
catch (Exception ex)
{
var stackBeforDispatch = ex.StackTrace;//get the stack trace before it is dispatched to keep track of the original error origin
var uiThread = Application.Current != null ? Application.Current.Dispatcher : Dispatcher.CurrentDispatcher;//try to find the ui dispatcher if any
Action action1 = action;
//dispatch to ui thread so that the information goes up to the user
uiThread.Invoke(new Action(() =>
{
ex.Source = ex.Source += string.Format("{0}From Thread: {0} {1}{0}From Method: {0} {2}{0}Stack trace before Dispatch: {0} {3}",
Environment.NewLine,
_dispatcherThread.Name,
action1.Method.Name,
stackBeforDispatch);
throw ex;
}));
}
对我来说,将调度程序优先级更改为较低优先级DispatcherPriority.SystemIdle
似乎解决了这个问题:现在,在后台线程中发生的所有异常都被正确地重新抛出到UI线程,在那里它们由DispatcherUnhandledException
。
实际上,我没有'明白为什么,我发现你的问题正在寻找解释:)
答案 3 :(得分:0)
这个问题很旧;尽管如此,现在类似的问题困扰着我的UWP应用。有时,我必须通过允许异常向上传播来释放调用堆栈。我需要异常才能到达应用程序的UnhandledException
处理程序,但这并不总是发生。此问题包括抛出非UI线程的明显情况。它也包括一个不明显的情况,引发UI线程。我尚未确定原因。
我想到了以下解决方案。我捕获了异常,然后将其显式发布到同步上下文。由于上述奇怪的问题,即使已经在当前同步上下文中运行,我也必须这样做。否则,异常有时不会到达UnhandledException
处理程序。
private void Throw( Exception exception )
{
uiContext.Post( arg => throw exception, null );
throw new OperationCanceledException();
}