【问题标题】:Exception Handling in Prism Async DelegateCommandPrism Async DelegateCommand 中的异常处理
【发布时间】:2017-05-12 13:54:16
【问题描述】:

我在异步 DelegateCommand (Prism 5) 中捕获异常时遇到了很多麻烦。

在 ViewModel 的构造函数中:

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

在 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

为什么没有捕获异常?我知道这是另一个线程,但无论如何它都应该被外部 Try...Catch 块 (Try Catch outside of: await Task.Run(()) 捕获。

注意:它是 vb.net 代码,但 C# 解决方案也可以。

更新 2 一旦我知道我的调试器配置有问题(第一次机会异常),我就写了一个更现实的例子:

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

现在当我按 F5 时它不会捕获异常。它在“throwMyException()”中中断,尽管在 Try Catch 块中调用它,但它不会捕获异常。

重要提示:如果我删除“throwMyException”中的 Async 词,它会捕获它!!!

我现在做错了什么?

谢谢

【问题讨论】:

  • 你确定这段代码不会捕获异常吗?
  • 我绝对确定我生命中的事情很少:) 但我已经粘贴并复制了代码,检查了它,它没有捕获异常。我打算用图片更新问题
  • 看起来你已经在调试器中打开了第一次机会异常。如果你从那里按 F5,它会被抓住吗?
  • 是的,确实如此!那么它在可执行文件中可以正常工作吗?
  • 我的调试器异常设置窗口中没有检查 System.Exception。为什么会停止?

标签: asynchronous prism delegatecommand


【解决方案1】:

您发布的原始代码没有问题 - 调试器只是在您的代码之前捕获了异常,这是完全正常的。

使用更新的代码,问题在于Async Sub 的使用。无法从Async Sub 方法中直接捕获异常。您应该改用(非AsyncSubAsync Func(of Task)。这个原则在我的MSDN article on async best practices 中被称为“避免异步无效”。

【讨论】:

  • 我做错了什么,因为我不明白。如果我将签名更改为“Private Async Function OnModificarPedido(arg As Object) As Task”,那么构造函数“cmdModificarPedido = New DelegateCommand(Of Object)(AddressOf OnModificarPedido, AddressOf CanModificarPedido)”中的这段代码呢?它显示此消息:“从此异步函数返回的任务将被删除,其中的任何异常都将被忽略。考虑将其更改为异步子,以便传播其异常”,并且也不会捕获异常。非常感谢
  • 方法错误。你应该改变throwMyException,而不是OnModificarPedido
  • 你是个天才!!!这正是问题所在!没有 async Sub 解决了我的问题(我无法使其与 Async Func(of Task) 一起工作)。谢谢
猜你喜欢
  • 1970-01-01
  • 2012-11-04
  • 2012-02-16
  • 2021-12-27
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
相关资源
最近更新 更多