What is the recommended way to handle errors when using Tasks to unblock the UI and using Aync/Await is not an option?
I typically want to handle expected errors by updating the UI and handle unexpected Errors (log Exception(s), inform user and shutdown app) in a global error handler like Application_DispatcherUnhandledException.
I am playing with the following approach which looks ugly to me.
Private Sub _showAsyncButton_Click(sender As Object, e As RoutedEventArgs) Handles _showAsyncButton.Click
Dim task = New WebClient().DownloadStringTaskAsync("http://www.microsoft.com")
'Dim task = New WebClient().DownloadStringTaskAsync("forcing error in async I/O")
task.ContinueWith(
Sub()
_resultField.Text = task.Result
'Throw New ApplicationException("forcing error in End method")
End Sub, Nothing, Nothing, TaskScheduler.FromCurrentSynchronizationContext
).ContinueWith(
Sub(a)
Select Case True
Case TypeOf (a.Exception.GetBaseException) Is WebException AndAlso CType(a.Exception.GetBaseException, WebException).Status = WebExceptionStatus.NameResolutionFailure
'Handle expected error
Dispatcher.Invoke(Sub() MessageBox.Show("Cannot access web site. Please try again later"))
Case Else
'Rethrow unexpected error in global error handler
Dispatcher.BeginInvoke(Sub() ExceptionDispatchInfo.Capture(a.Exception).Throw())
'ExceptionDispatchInfo.Capture(aex).Throw() 'Does not work
End Select
End Sub, TaskContinuationOptions.OnlyOnFaulted)
End Sub
Handling exceptions in a parallel application alongside handling many other stuff is a painful task and requires sufficient knowledge and skill. Consider re-writing the above code using
async-awaitkeywords introduced in .Net 4.5, it then allows you to handle exceptions in the same way you did in a synchronous programming model. Of course, there exists some situations whenasync-awaitis not adequate and you need to directly use TPL API.You could then use a .Net decompiler (i.e. .Net Reflector) to see how much work compiler did on behalf of you, it would also be an invaluable learning source.
Also Consider taking a look at Exception Handling with the Task Parallel Library which provides you with a good insight on how to deal with exceptions when doing parallel programming using TPL.
The “The zen of async: Best practices for best performance” presented by Stephen Toub also dives deeply into how
asyncworks under the hoods in .Net 4.5 and it covers some advanced topics which exception handling is one of those.