gpt4 book ai didi

.net - 在 Try/Catch 内部,Visual Studio 中断并结束未处理异常的应用程序

转载 作者:行者123 更新时间:2023-12-05 03:13:47 25 4
gpt4 key购买 nike

在 Visual Studio 内外运行相同的代码时,我会遇到不同的行为。

Private Sub MyApplication_Startup(...) Handles Me.Startup
'--- handler for unhandled exceptions
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExHandler
'--- handler 0
AddHandler System.Windows.Forms.Application.ThreadException, AddressOf ThreadExHandler
Utils.RememberMainThreadId()
End Sub

Sub OpenMyForm() 'entry point
Debug.Assert(Utils.RunningOnMainThread())
Try
MyForm.Show()
Catch ex As Exception '--- handler 1
LogError(ex) '--- goes here only if launched outside the Visual Studio
End Try
End Sub

Sub MyForm_Load() Handles MyBase.Load
Debug.Assert(Utils.RunningOnMainThread())
FillMyDataTable() '---if I put try/catch here, it will always work (tested)
End Sub

Sub FillMyDataTable()
Try
New SqlClient.SqlDataAdapter(sqlCmd).Fill(myDataTable)
Catch ex As Exception '--- handler 2
If ex.Number = Constants.ConnectionBroken then
ReconnectRetry()
Else
Throw '--- enters UnhandledExHandler() when in Visual Studio
End If
End Try
End Sub

在 Visual Studio 中,错误的 SQL 命令会转到UnhandledExHandler(),但如果在 VS 外部启动相同的 EXE,则会触发 Wrapper() 内的 Catch ex As Exception(这是预期结果)。这里有什么问题?

  • Visual Studio 错误消息是 “System.Data.SqlClient.SqlException”类型的未处理异常发生在 filename.exe 中

  • 这是在调用 MyForm.Show() 期间发生的,它间接调用 MyForm_Load() 事件处理程序并调用 MyComboBox_SelectedIndexChanged() 事件处理程序(并且此事件处理程序间接执行查询)。

  • 如果我在异常中断期间找到并单击 Wrapper() 堆栈帧,我可以看到位于 之间的对 FillMyDataTable() 的突出显示调用尝试/Catch

  • 我总是在主线程上(ManagedThreadIdStartup 事件期间存储,然后验证它的多个断言被插入到上面的代码中)。

  • 除了最底部的框架(System.Windows.Forms.NativeWindow.DebuggableCallback()System.Windows.Forms 之外,堆栈跟踪完全相同(通过 diff 检查) .NativeWindow.Callback()).

    • 最顶层的框架是 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, bool breakConnection)
  • 直到昨天才出现这个问题。我想我已经更改了一些选项。

  • 重新启动 Visual Studio 没有帮助。

  • 如果启用或禁用异常助手,行为不会发生变化。

  • 选项和异常设置是这样的:
    enter image description here
    enter image description here

  • 堆栈跟踪是:

myApp.exe!myApp.frmAPP_PrenosWizard.frmFT_PrenosWizard_Load(Object sender, System.EventArgs e) Line 125 BasicSystem.Windows.Forms.dll!System.Windows.Forms.Form.OnLoad(System.EventArgs e) + 0x1d5 bytes System.Windows.Forms.dll!System.Windows.Forms.Form.OnCreateControl() + 0x55 bytes   System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl(bool fIgnoreVisible) + 0x181 bytes  System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl() + 0x24 bytes  System.Windows.Forms.dll!System.Windows.Forms.Control.WmShowWindow(ref System.Windows.Forms.Message m) + 0x98 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x2b6 bytes System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x2a bytes    System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) + 0x10 bytes System.Windows.Forms.dll!System.Windows.Forms.Form.WmShowWindow(ref System.Windows.Forms.Message m) + 0x41 bytes    System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x154 bytes    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x10 bytes    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x31 bytes  System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes [Native to Managed Transition]  [Managed to Native Transition]  System.Windows.Forms.dll!System.Windows.Forms.UnsafeNativeMethods.CreateWindowEx(int dwExStyle, string lpszClassName, string lpszWindowName, int style, int x, int y, int width, int height, System.Runtime.InteropServices.HandleRef hWndParent, System.Runtime.InteropServices.HandleRef hMenu, System.Runtime.InteropServices.HandleRef hInst, object pvParam) + 0x3c bytes  System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams cp) + 0x225 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() + 0x125 bytes  System.Windows.Forms.dll!System.Windows.Forms.Form.CreateHandle() + 0x9f bytes  System.Windows.Forms.dll!System.Windows.Forms.Control.Handle.get() + 0x45 bytes System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value) + 0x160 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.Show() + 0x10 bytes   myApp.exe!myApp.APP.clsPrenos.ZobrazWizard(myApp.frmAPP_PrenosWizard.enRezimPrenosu rezim, myApp.APP.clsEntita.enEntita zdrojEntita, Integer zdrojID, myApp.APP.clsEntita.enEntita cielEntita, Integer cielID, System.Data.SqlClient.SqlConnection cn1) Line 8212 + 0xa bytes   BasicmyApp.exe!myApp.frmMain.FCreateTransferUI(myApp.frmAPP_PrenosWizard.enRezimPrenosu mode, myApp.APP.clsEntita.enEntita sourceEntity, Integer sourceID, myApp.APP.clsEntita.enEntita targetEntity, Integer targetID, System.Data.SqlClient.SqlConnection cn1) Line 2410 + 0x17 bytes  BasicmyApp.exe!myApp.frmMain.frmMain_Receive(Object sender, myApp.clsFisCommandProcessor.ReceivedEventArgs e) Line 239 + 0xa7 bytes  BasicmyApp.exe!myApp.clsFisCommandProcessor.raise_Received(Object sender, myApp.clsFisCommandProcessor.ReceivedEventArgs e) Line 96 + 0x2e bytes BasicmyApp.exe!myApp.clsFisCommandProcessor.Execute(myApp.clsFisCommand command, Object sender) Line 136 + 0x57 bytes    BasicmyApp.exe!myApp.clsFisCommandProcessor.Execute(myApp.clsFisCommand() commands, Object sender) Line 128 + 0x27 bytes BasicmyApp.exe!myApp.clsFisCommandProcessor.Execute(String scan, Boolean requireMarking, Object sender) Line 122 + 0x30 bytes    BasicmyApp.exe!myApp.frmCommandPad.TSMI_Execute_Click(Object sender, System.EventArgs e) Line 94 + 0x51 bytes    BasicSystem.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.RaiseEvent(object key, System.EventArgs e) + 0x58 bytes System.Windows.Forms.dll!System.Windows.Forms.ToolStripMenuItem.OnClick(System.EventArgs e) + 0x46 bytes    System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.HandleClick(System.EventArgs e) + 0x6e bytes    System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEventInteractive(System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) + 0x83 bytes  System.Windows.Forms.dll!System.Windows.Forms.ToolStripItem.FireEvent(System.EventArgs e, System.Windows.Forms.ToolStripItemEventType met) + 0x118 bytes    System.Windows.Forms.dll!System.Windows.Forms.ToolStripMenuItem.ProcessCmdKey(ref System.Windows.Forms.Message m, System.Windows.Forms.Keys keyData) + 0x47 bytes   System.Windows.Forms.dll!System.Windows.Forms.ToolStripManager.ProcessShortcut(ref System.Windows.Forms.Message m, System.Windows.Forms.Keys shortcut) + 0x2dc bytes    System.Windows.Forms.dll!System.Windows.Forms.ToolStripManager.ProcessCmdKey(ref System.Windows.Forms.Message m, System.Windows.Forms.Keys keyData) + 0x2d bytes    System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x3c bytes  System.Windows.Forms.dll!System.Windows.Forms.Form.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x29 bytes  System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes   System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0xda bytes   System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessMessage(ref System.Windows.Forms.Message msg) + 0x90 bytes  System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessControlMessageInternal(System.Windows.Forms.Control target, ref System.Windows.Forms.Message msg) + 0x101 bytes System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(ref System.Windows.Forms.NativeMethods.MSG msg) + 0xf6 bytes    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(ref System.Windows.Forms.NativeMethods.MSG msg) + 0x5 bytes System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason, int pvLoopData) + 0x22e bytes  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x177 bytes  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes    System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x18 bytes Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() + 0x81 bytes    Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() + 0xef bytes   Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(string[] commandLine) + 0x68 bytes  [Native to Managed Transition]  [Managed to Native Transition]  mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.Assembly assembly, string[] args) + 0x19 bytes mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0x6e bytes mscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x84 bytes mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x65 bytes mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0xa bytes mscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext) + 0x3e bytes   Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x23 bytes   mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes   mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   

最佳答案

这个问题有很多变化的部分,我不确定我能否公正地回答所有这些问题。出发点是,如果您使用调试器,则不应订阅这些事件。用 If Not System.Diagnostics.Debugger.IsAttached Then 包装该代码,以便您可以正确诊断和修复未处理的异常。

一个重要的随机化器是 Load 事件处理程序中抛出的异常。 Microsoft 在正确处理 Windows 回调处于事件状态时引发的异常时遇到了很多麻烦。例如导致 Load 事件触发的那个。他们在 Vista 上改变了规则,在 Win7 上又一次在 Win8 上改变了规则。如果您运行 64 位版本的 32 位版本,它们会有所不同。以及您的程序是作为 32 位还是 64 位进程运行。使用调试器会改变行为。出现异常时可能会出现程序兼容性助手,询问您是否希望您的程序“兼容”。每个人都说是的,当然,这是一个非常糟糕的主意。将它们相加,您可以获得三十二种 不同结果中的一种。哎哟。

它在 this MSDN article 中有正式描述但没有人理解。直到它没有达到他们希望的效果,在一个问题中涵盖 like this one .缓解情况是,当您调试应用程序时,这只是字节,消息循环中的正常异常回退确保这不会在您的用户机器上失控。换句话说,当您按 Ctrl+F5 或使用资源管理器运行该程序时,您看到的就是您期望它的工作方式。

这个问题会影响 Windows 上的任何 GUI 程序。但它有一个诀窍,在 Winforms 应用程序中特别麻烦,程序员完全使用 Load 事件太多。由于它是 Form 类的默认事件而误入歧途,只需双击即可生成它。特别是在 VB.NET 中,它不会自动创建窗体的构造函数,而 Visual Basic 有使用 Load 事件初始化窗体的传统,可以追溯到 VB6。

我通常避免判断我看到的编程实践,但由于这些问题,今天使用 Load 事件确实是一种相当糟糕的实践。始终倾向于使用构造函数来初始化类,这是任何 .NET 程序员都知道的规则,对于 Form 类来说也不异常(exception)。 必须使用 Load 的理由非常少,详见 this post .

关于.net - 在 Try/Catch 内部,Visual Studio 中断并结束未处理异常的应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28781435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com