2016-12-28 5 views
0

非同期DelegateCommand(Prism 5)で例外をキャッチするのに苦労しています。ビューモデルのコンストラクタでPrism Async DelegateCommandの例外処理

:ViewModelにで

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

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 

例外がcatchedされていないのはなぜ?私はそれが別のスレッドだと知っていますが、とにかく外部Try ... Catchブロック(Try Catch outside of: await Task.Run(())によってキャッチされるはずです。

enter image description here

注:それはvb.netコードですが、C#ソリューションがあまりにも罰金になります。

UPDATE 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」で非同期ワードを削除すると、それをキャッチします。

私は今何が間違っていますか?あなたのコードがした前に、デバッガは、単に例外をキャッチして、完全に正常である -

は、あなたが投稿元のコードに問題はありませんでした

+0

*このコード*が例外をキャッチしないことは間違いありませんか? –

+0

私は人生の中で非常に少ないことを絶対に確信しています:)しかし、コードをペーストしてコピーしてチェックし、例外をキャッチしません。私は画像で質問を更新するつもりです –

+1

あなたはデバッガで最初のチャンスの例外がオンになっているように見えます。あなたがそこからF5を取れば、捕まえられるのだろうか? –

答えて

0

ありがとうございます。

更新されたコードでは、問題はAsync Subの使用です。例外は直接Async Subメソッドからキャッチできません。代わりに(Async以外)SubまたはAsync Func(of Task)を使用する必要があります。この原則は私のMSDN article on async best practicesの "async voidを避ける"と呼ばれています。

+0

私はそれを取得しないため、私は間違って何かをしています。私が "Private Async Function OnModificarPedido(arg As Object)As Task"に変更した場合、コンストラクタ "cmdModificarPedido = New DelegateCommand(Of Object)(AddressOf OnModificarPedido、AddressOf CanModificarPedido)"のこのコードはどうですか? 「この非同期関数から返されたタスクは破棄され、その中の例外は無視されます。非同期Subに変更してその例外が伝播されるよう考慮する」と例外がキャッチされません。ありがとうございます –

+1

間違った方法です。 'OnModificarPedido'ではなく' throwMyException'を変更する必要があります。 –

+0

あなたは天才です!それはまさに問題でした!非同期Subは私の問題を解決しなかった(私はAsync Func(of Task)で動作させることができなかった)。ありがとうございました –