Exception Handling in Prism Async DelegateCommand

499 Views Asked by At

I am having a lot of troubles to catch an exception in a async DelegateCommand (Prism 5).

In constructor of the ViewModel:

cmdModificarPedido = New DelegateCommand(Of Object)(AddressOf OnModificarPedido, AddressOf CanModificarPedido)

In the ViewModel:

Private _cmdModificarPedido As DelegateCommand(Of Object)
Public Property cmdModificarPedido As DelegateCommand(Of Object)
    Get
        Return _cmdModificarPedido
    End Get
    Private Set(value As DelegateCommand(Of Object))
        SetProperty(_cmdModificarPedido, value)
    End Set
End Property
Private Function CanModificarPedido(arg As Object) As Boolean
    Return True
End Function
Private Async Sub OnModificarPedido(arg As Object)
    Try
        Await Task.Run(Sub()
                           Throw New Exception("My Exception")
                       End Sub)
        NotificationRequest.Raise(New Notification() With {
                       .Title = "OK",
                       .Content = "Command OK"
                   })

    Catch ex As Exception
        NotificationRequest.Raise(New Notification() With {
                    .Title = "Error",
                    .Content = ex.Message
                })

    End Try
End Sub

Why the Exception is not being catched? I know it is another thread, but it is supposed to be catched anyway by the external Try...Catch block (Try Catch outside of: await Task.Run(()).

enter image description here

Note: it is vb.net code, but a C# solution will be fine too.

UPDATE 2 Once I know there was a problem with my debugger configuration (first chance exceptions), I write a more realistic example with same problem:

Private Async Sub OnModificarPedido(arg As Object)
    Try
        Await Task.Run(Sub()
                           Try
                               throwMyException()
                           Catch ex As Exception
                               Throw New Exception(ex.Message)
                           End Try
                       End Sub)
        NotificationRequest.Raise(New Notification() With {
                       .Title = "Pedido Modificado",
                       .Content = "Pedido " + pedido.numero.ToString + " modificado correctamente"
                   })

    Catch ex As Exception
        NotificationRequest.Raise(New Notification() With {
                    .Title = "Error",
                    .Content = ex.Message
                })

    End Try
End Sub
Public Async Sub throwMyException()
    Throw New Exception("My Exception")
End Sub

And now it does not catch the exception when I press F5. It breaks in "throwMyException()", it does not catch the exception although it is called inside a Try Catch block.

Important: If I remove the Async word in "throwMyException", it does catch it!!!

What am I doing wrong now?

Thank you

1

There are 1 best solutions below

3
On BEST ANSWER

There was no problem with the original code you posted - the debugger was just catching the exception before your code did, which is perfectly normal.

With the updated code, the problem is the use of Async Sub. Exceptions cannot be directly caught from Async Sub methods. You should use (non-Async) Sub or Async Func(of Task) instead. This principle is known as "avoid async void" in my MSDN article on async best practices.