You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET 2022未处理异常无法被处理器捕获问题求助

VB.NET WinForms .NET Framework 4.8 全局异常处理器未触发问题

问题描述

使用VB.NET 2022开发基于.NET Framework 4.8的Windows Forms应用,已配置全局异常处理代码,但在Button点击事件中抛出测试异常时,调试器会在Throw语句处暂停,继续运行后应用直接终止,未触发任何异常处理器。

配置的异常处理代码

MyApplication 类代码

Namespace My
  Partial Friend Class MyApplication
    Public Shared Sub Thread_ExceptionEventHandler(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
      WriteLog("Application_Thread_Exception", sender, e.Exception.Message)
    End Sub
    Public Shared Sub AppDomain_FirstChanceException(ByVal sender As Object, ByVal e As Runtime.ExceptionServices.FirstChanceExceptionEventArgs)
      WriteLog("App_Domain_First_Chance_Exception", sender, e.Exception.Message)
    End Sub

    Private Overloads Function OnStartup(e As ApplicationServices.StartupEventArgs) As Boolean
      AddHandler Windows.Forms.Application.ThreadException, AddressOf Thread_ExceptionEventHandler
      AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf AppDomain_FirstChanceException
      Return MyBase.OnStartup(e)
    End Function

    Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
      WriteLog("Application_Unhandled_Exception", sender, e.Exception.ToString)
    End Sub

    Private Sub MyApplication_NetworkAvailabilityChanged(sender As Object, e As Devices.NetworkAvailableEventArgs) Handles Me.NetworkAvailabilityChanged
      WriteLog("Application_Network_Availability", sender, e.IsNetworkAvailable.ToString)
    End Sub

    Public Shared Sub WriteLog(name As String, sender As Object, eMsg As String)
      Dim logPath As String = System.IO.Path.Combine(My.Application.Info.DirectoryPath, name)
      If Not System.IO.Directory.Exists(logPath) Then MkDir(logPath)
      Dim fullPath As String = System.IO.Path.Combine(logPath, $"{name}-{Format(Now, "yyyy.MM.dd")}.txt")

      Using sw = New IO.StreamWriter(fullPath, True)
        sw.WriteLine($"«««{vbCrLf}{Format(Now, "yyyy/MM/dd HH:mm:ss")}{vbCrLf}{name}: {sender}{vbCrLf}{eMsg}{vbCrLf}»»»")
      End Using
    End Sub
  End Class
End Namespace

测试用Button点击事件

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  Throw New Exception("testing exception handling")
End Sub

问题原因分析

  1. 调试器默认行为干扰:Visual Studio调试模式下,默认会捕获所有未处理异常并暂停执行,导致应用的异常处理器无法触发。
  2. 未设置WinForms异常处理模式:默认情况下,WinForms会将UI线程异常优先交给调试器处理,未显式授权应用自身处理。
  3. 未标记异常为已处理:即使ThreadExceptionEventHandler被触发,若未设置e.Handled = True,应用仍会因未处理异常终止。

解决方案

1. 调整WinForms异常处理模式

在OnStartup方法中添加SetUnhandledExceptionMode调用,强制应用处理UI线程异常:

Private Overloads Function OnStartup(e As ApplicationServices.StartupEventArgs) As Boolean
  ' 强制WinForms将UI线程异常交给应用处理器,而非调试器
  Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
  AddHandler Windows.Forms.Application.ThreadException, AddressOf Thread_ExceptionEventHandler
  AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf AppDomain_FirstChanceException
  Return MyBase.OnStartup(e)
End Function

2. 标记异常为已处理

修改ThreadExceptionEventHandler,添加e.Handled = True,确保处理完异常后应用继续运行:

Public Shared Sub Thread_ExceptionEventHandler(ByVal sender As Object, ByVal e As Threading.ThreadExceptionEventArgs)
  WriteLog("Application_Thread_Exception", sender, e.Exception.Message)
  e.Handled = True ' 标记异常已处理,避免应用终止
End Sub

3. 调试器设置调整(可选)

若想在调试时避免被异常打断,可:

  • 打开「调试」→「选项」→「调试」→「常规」,取消勾选「启用仅我的代码」。
  • 打开「调试」→「异常设置」,取消勾选「Common Language Runtime Exceptions」下的「抛出」选项(或仅针对特定异常取消)。

验证

修改完成后,再次触发Button点击异常:

  • 调试模式下,若调试器仍暂停,按F5继续后,ThreadExceptionEventHandler会触发并写入日志,应用不会终止。
  • 发布模式下,异常会直接被处理器捕获,应用正常运行。

内容的提问来源于stack exchange,提问作者CodeRed2550000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:55:04