堅牢性のために、TaskScheduler.UnobservedTaskExceptionのハンドラーを追加します。ハンドラーは例外をログに記録し、ユーザーに通知してアプリをシャットダウンします。
次の実装は意味がありますか?WPFでこのハンドラーにMessageBoxまたはWindowsを表示しても問題ありませんか、それとも監視されていないタスクのファイナライザーで実行しているため、これは悪い考えですか?
Private Sub TaskSheduler_UnobservedTaskException(sender As Object, e As UnobservedTaskExceptionEventArgs)
Static _wasUserInformed As Boolean = False
e.SetObserved()
'Trace all Exceptions
e.Exception.Flatten.Handle(Function(ex As Exception)
'TODO trace and log Exception
Debug.Print("UnobservedTaskException: {0}", ex.Message)
Return True
End Function)
If Not _wasUserInformed Then
'Show root Exception
_wasUserInformed = True
Application.Current.Dispatcher.BeginInvoke(Sub()
'MessageBox.Show(e.Exception.GetBaseException.Message)
Dim win As New UnexpectedExceptionWindow
win.UnexpectedException = e.Exception.GetBaseException
win.ShowDialog()
Application.Current.Dispatcher.BeginInvoke(Sub() Application.Current.Shutdown())
End Sub)
End If
サブ終了
[編集]私たちの議論の結果、私は次の解決策を思いつきました。
Private Sub TaskScheduler_UnobservedTaskException(sender As Object, e As UnobservedTaskExceptionEventArgs
) Handles TaskScheduler.UnobservedTaskException
Static _wasUserInformed As Boolean = False
'Free the finalizer thread and execute on the UI thread to be able to inform user
Dispatcher.BeginInvoke(Sub() LogException(e.Exception))
e.SetObserved()
If Not _wasUserInformed Then
_wasUserInformed = True
'Show first error
Dispatcher.BeginInvoke(Sub()
NotifyUser(e.Exception)
Application.Current.Shutdown()
End Sub)
End If
End Sub