Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
捕获WPF中非UI线程的所有异常处理程序_Wpf_Vb.net_Mvvm_Exception Handling_Unobserved Exception - Fatal编程技术网

捕获WPF中非UI线程的所有异常处理程序

捕获WPF中非UI线程的所有异常处理程序,wpf,vb.net,mvvm,exception-handling,unobserved-exception,Wpf,Vb.net,Mvvm,Exception Handling,Unobserved Exception,具体来说,我将WPF与MVVM一起使用。我有一个主窗口,这是一个WPF窗口,所有的动作都发生在这里。它将相应的视图模型类用于其属性、命令等 我在Application.xaml.vb启动中设置了主UI线程和非UI线程异常处理程序,如下所示: Private子应用程序\u DispatcherUnandledException(发件人作为对象,e作为Windows.Threading.DispatcherUnandledExceptionEventArgs)处理Me.DispatcherUnand

具体来说,我将WPF与MVVM一起使用。我有一个主窗口,这是一个WPF窗口,所有的动作都发生在这里。它将相应的视图模型类用于其属性、命令等

我在Application.xaml.vb启动中设置了主UI线程和非UI线程异常处理程序,如下所示:

Private子应用程序\u DispatcherUnandledException(发件人作为对象,e作为Windows.Threading.DispatcherUnandledExceptionEventArgs)处理Me.DispatcherUnandledException
'仅捕获主UI线程异常
ShowDebugOutput(例如异常)
e、 已处理=真
端接头
私有子应用程序_Startup(发送方作为对象,e作为StartupEventArgs)处理我。Startup
'捕获背景异常
将currentDomain设置为AppDomain=AppDomain.currentDomain
AddHandler currentDomain.UnhandledException,UnhandledExceptionHandler的地址
AddHandler System.Threading.Tasks.TaskScheduler.UnobservedTaskException,BackgroundTaskExceptionHandler的地址
端接头
子UnhandledExceptionHandler(发送方作为对象,参数作为UnhandledExceptionEventArgs)
Dim ex As Exception=DirectCast(args.ExceptionObject,Exception)
ShowDebugOutput(ex)
端接头
Sub-BackgroundTaskExceptionHandler(发送方作为对象,参数作为System.Threading.Tasks.UnobservedTaskExceptionEventArgs)
Dim ex As Exception=DirectCast(args.Exception,Exception)
ShowDebugOutput(ex)
端接头
这部分有效 当我试图通过故意抛出异常来测试这一点时,它是有效的。实际上,它位于子对象中处理“全选”按钮单击的视图模型中

按钮:

<Button Content="Select All" Height="23" Width="110" Command="{Binding SelectAllCommand}" />
这部分不行 在同一主窗口中,还有另一个按钮类似地绑定到命令。但是,它使用一个任务在后台执行它的工作,在那里抛出的异常不会被我的“捕获所有”处理程序捕获

Private Sub-GeneratePreview()
“在后台运行
System.Threading.Tasks.Task.Factory.StartNew(
分()
“…被剪掉的东西,问题是相同的,无论是否有剩余的代码在这里。。。
抛出(新异常(“抛出后台线程异常”))
末端接头)
端接头
有几个类似的问题,但我还不能从中找出我的答案。AppDomain UnhandledException似乎是大多数情况下的答案,但对我来说不是。为了捕获可能以这种方式在非UI线程中抛出的异常,我必须添加什么

我最终做了什么 当我在Application.xaml.vb中处理TaskScheduler.UnobservedTaskException事件时,我无法让它调用我的事件处理程序。但我从另一个答案中得到了一些提示,我将把它标记为答案,因为它最终起到了帮助作用

但是,它不在应用程序级别,因此如果这是一个更大的应用程序,我必须在使用任务的每个实例中复制它。这不是我真正想要的,但我现在不愿意花更多的时间在上面

最后,我在任务中加入了一个try-catch。在catch中,我能够使用Dispatcher.Invoke仍然显示一个带有异常信息的用户友好对话框

Private Sub-GeneratePreview()
“在后台运行
System.Threading.Tasks.Task.Factory.StartNew(
分()
尝试
“…被剪掉的东西,问题是相同的,无论是否有剩余的代码在这里。。。
抛出(新异常(“抛出后台线程异常”))
特例
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal,DirectCast(
分()
HRNetToADImport.Application.ShowDebugOutput(ex)
结束(行动小组)
结束尝试
末端接头)
端接头
桑德拉

有一种方法可以从后台任务中捕获异常。
我承认我的解决方案不是全球性的,但至少它抓住并防止了崩溃

Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
    Dim t As Task = Task.Factory.StartNew(
       Sub()
           ' ... stuff snipped out, issue is the same with or without the rest of the code here ...
           Throw (New Exception("Throwing a background thread exception"))
       End Sub)
    Try
        Await t
    Catch ex1 As Exception
        Debug.WriteLine("Exception from inside task " & ex1.Message)
    End Try
End Sub

我想这可能会有帮助,可能是你,可能是其他人

TaskScheduler.UnobservedTaskException事件是您要从应用程序启动订阅的事件

当出现故障的任务的未观察到的异常即将触发异常升级策略时发生,默认情况下,该策略将终止该进程

此AppDomain范围的事件提供了一种机制来防止触发异常升级策略(默认情况下,该策略会终止进程)

注意:事件可能不会立即触发(可能会延迟几秒钟)。您可以想象,在到达UnobservedTaskeException事件之前,有一些调用堆栈冒泡和正常异常操作的上下文切换操作

我想指出的一点是,必须用通用异常处理程序包装整个应用程序,以防止应用程序终止。但是,请记住,对所有可能引发异常的路径实施适当的异常处理也是必须的。

Sandra

我读了cscmh99提案, 把你的代码,并尝试运行,它的工作

我的意思是你可以订阅
任务调度程序。未观察到的任务异常

  • 然后您将捕获
    未观察到的异常

  • 但您不会捕获观察到的异常 观察到的异常是使用
    .Wait()
    .Result
    等待的任务中的异常

Private子按钮\u单击(发送者作为对象,e作为RoutedEventArgs)
下面是一个未被发现的例外
System.Threading.Tasks.Task.Factory.StartNew(
分()
抛出(新异常(“抛出后台线程异常”))
末端接头)
下面是一个观察到的例外
'ObservedException,因为调用了.Wait()(或.Result)
“你不能使用UnobservedExcepti