问题
I have the following code in my WPF application:
Task task = Task.Factory.StartNew(() => {
DoInitialProcess();
});
task.ContinueWith(t =>
Dispatcher.BeginInvoke((Action)(() => {
MessageBox.Show("Error: " + t.Exception.InnerExceptions[0].Message);
})), TaskContinuationOptions.OnlyOnFaulted);
It successfully triggers the continuation and displays the message box if an exception occurs, but it does not block input on the main UI thread.
Why doesn't it block the main UI thread, and what is the best approach to make it do so?
回答1:
In general, the way this would typically be done is via a proper TaskScheduler
, not via Dispatcher.BeginInvoke
. Try the following:
task.ContinueWith(t =>
{
MessageBox.Show("Error: " + t.Exception.InnerExceptions[0].Message);
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
Provided you're creating this task in the UI thread, the above should work the way you expect.
If, however, you're starting this task on a background thread, you'll need to provide a clean way to get the proper TaskScheduler
to the continuation. This can be done by grabbing the scheduler during a window's construction or some other means, and then using it later.
来源:https://stackoverflow.com/questions/8932805/using-the-net-4-task-library-to-display-a-blocking-message-box-in-wpf