-
Notifications
You must be signed in to change notification settings - Fork 129
WPF Dispatcher BeginInvoke vs. InvokeAsync
jbe2277 edited this page May 25, 2018
·
3 revisions
The WPF Dispatcher class comes with two different methods to execute a delegate asynchronously on the Dispatcher thread:
The major difference between these two methods is how they handle Exceptions.
Quick guideline: If you are using
await
then preferInvokeAsync
. Otherwise useBeginInvoke
.
The following code sample explains the Exception handling behavior of both methods:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Dispatcher.UnhandledException += OnUnhandledException;
}
private void OnUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("UnhandledException");
// App crashes after raising this event if Handled is not set to true.
e.Handled = true;
}
private void BeginInvoke1Click(object sender, RoutedEventArgs e)
{
// This will raise the UnhandledException event.
Dispatcher.BeginInvoke((Action)(() => throw new Exception()));
}
private async void BeginInvoke2Click(object sender, RoutedEventArgs e)
{
// Don't use BeginInvoke when using await as the catch handler is ignored.
try
{
await Dispatcher.BeginInvoke((Action)(() => throw new Exception()));
}
catch
{
MessageBox.Show("BeginInvoke"); // Will never be called.
}
}
private async void InvokeAsync1Click(object sender, RoutedEventArgs e)
{
// This behaves similar to BeginInvoke1Click regarding exception handling.
await Dispatcher.InvokeAsync(() => throw new Exception());
}
private async void InvokeAsync2Click(object sender, RoutedEventArgs e)
{
try
{
await Dispatcher.InvokeAsync(() => throw new Exception());
}
catch
{
MessageBox.Show("InvokeAsync");
}
}
private void InvokeAsync3Click(object sender, RoutedEventArgs e)
{
// Don't use InvokeAsync without await as the exception is tracked
// as unobserved exception and might be missed.
Dispatcher.InvokeAsync(() => throw new Exception());
}
}