Why exceptions are not propagated by WPF Dispatcher.Invoke?

孤街醉人 提交于 2019-12-03 10:42:34

UPDATED: To observe the exception in the other thread, you want to use a Task, queue it to the Dispatcher thread (using TaskScheduler.FromCurrentSynchronizationContext), and wait on it, as such:

var ui = TaskScheduler.FromCurrentSynchronizationContext();
Action doit = () => 
{ 
    var error = Task.Factory.StartNew(
        () => { throw new InvalidOperationException("test"); },
        CancellationToken.None,
        TaskCreationOptions.None,
        ui); 

    try { 
        error.Wait(); 
    } catch (Exception ex) { 
        System.Diagnostics.Trace.WriteLine(ex); 
    } 
}; 
doit.BeginInvoke(null, null); 

UPDATED (again): Since your goal is a reusable component, I do recommend moving to a Task-based interface or something else based on SynchronizationContext such as the event-based asynchronous pattern, instead of basing the component on Dispatcher or ISynchronizeInvoke.

Dispatcher-based components only work on WPF/Silverlight; ISynchronizeInvoke-based components only work on Windows Forms. SynchronizationContext-based components will work with WPF or Windows Forms transparently, and (with a bit more work) ASP.NET, console apps, windows services, etc.

The event-based asynchronous pattern is the old recommended way of writing SynchronizationContext-based components; it's still around for .NET 3.5-era code. If you're on .NET 4, though, the task parallel library is much more flexible, clean, and powerful. The TaskScheduler.FromCurrentSynchronizationContext uses SynchronizationContext underneath, and is the New Way to write reusable components that need this kind of synchronization.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!