这是我发现的短短数天前,我得到了确认,这并不仅仅局限于我的机器从这个问题.
重新编写它的最简单方法是启动Windows窗体应用程序,添加一个按钮并编写以下代码:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
Run Code Online (Sandbox Code Playgroud)
执行Exit()语句后程序失败.在Windows窗体上,您会收到"创建窗口句柄时出错".
启用非托管调试可以清楚地了解发生了什么.在COM模式循环正在执行,并允许待递送WM_PAINT消息.处置表格上的这是致命的.
到目前为止我收集的唯一事实是:
我特别感兴趣的是你可能做些什么来避免这次崩溃.特别是AppDomain.UnhandledException场景让我感到困惑; 没有很多方法可以终止.NET程序.请注意,调用Application.Exit()或Form.Close()在UnhandledException的事件处理程序中无效,因此它们不是变通方法.
更新:Mehrdad指出终结器线程可能是问题的一部分.我想我已经看到了这一点,并且我也看到了CLR给终结器线程完成执行的2秒超时的一些证据.
终结器位于NativeWindow.ForceExitMessageLoop()内.那里有一个IsWindow()Win32函数,大致对应于代码位置,在32位模式下查看机器代码时偏移量为0x3c.似乎IsWindow()正在陷入僵局.我无法获得内部的良好堆栈跟踪,但调试器认为P/Invoke调用刚刚返回.这很难解释.如果你能获得更好的堆栈跟踪,那么我很乐意看到它.矿:
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.ForceExitMessageLoop() + 0x3c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Finalize() + 0x16 bytes
[Native to Managed Transition]
kernel32.dll!@BaseThreadInitThunk@12() + 0xe bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Run Code Online (Sandbox Code Playgroud)
ForceExitMessageLoop调用之上没有任何内容,启用了非托管调试器.
到目前为止,我只是在程序Application.Run的Program.cs入口点周围放置一个try/catch块.这会在调试模式下很好地捕获所有异常,但是当我在没有调试模式的情况下运行程序时,不再处理异常.我得到了未处理的异常框.
我不希望这种情况发生.我希望在非调试模式下运行时捕获所有异常.该程序有多个线程,最好是来自它们的所有异常都被同一个处理程序捕获; 我想记录数据库中的异常.有没有人对如何做到这一点有任何建议?
当我创建一个新项目时,我对未处理的异常会有一个奇怪的行为.这就是我可以重现问题的方法:
1)创建一个新的Windows窗体应用程序(C#,. NET Framework 4,VS2010)
2)将以下代码添加到Form1_Load处理程序:
int vara = 5, varb = 0;
int varc = vara / varb;
int vard = 7;
Run Code Online (Sandbox Code Playgroud)
我希望VS中断并在第二行显示未处理的异常消息.但是,会发生的是第三行只是跳过而没有任何消息,应用程序一直在运行.
我现有的C#项目没有这个问题.所以我想我的新项目是用一些奇怪的默认设置创建的.
有没有人知道我的项目有什么问题?
我试过检查Debug-> Exceptions中的方框.但即使我在try-catch块中处理异常,执行也会中断; 这也不是我想要的.如果我没记错的话,在这个对话框中有一个名为"未处理的异常"的列或者类似的东西,这会让我感到非常兴奋.但在我的项目中只有一列("Thrown").
我在VB.NET中创建了一个项目.如果我创建的应用程序将产生不需要的错误,它将创建一个包含错误的文本文件.我在Visual Studio上运行时能够执行此操作,但在运行单独的应用程序时,它不起作用,在bin/Debug上找到可执行文件.
这就是我所做的:
Sub Main(ByVal ParamArray args() As String)
Try
System.Windows.Forms.Application.Run(New Form1)
Catch ex As Exception
WriteErrorLogs(ex)
End Try
End Sub
Sub WriteErrorLogs(Byval ex As Exception)
' create a textfile the write x.Message, x.Source, x.ToString
Dim dnow As String = Now.ToString
Dim filename As String = "Error " & removeInvalidChars(dnow)
Dim saveto As String = New IO.FileInfo("Errors/" & filename).FullName & ".txt"
Dim title As String = ex.Message
Dim stacktrce As String = ex.StackTrace
If Not IO.Directory.Exists(New IO.DirectoryInfo("Errors").FullName) Then IO.Directory.CreateDirectory("Errors")
Dim …Run Code Online (Sandbox Code Playgroud)