捕获所有未处理的异常

问题描述:

我将在Winforms应用程序中捕获所有未处理的异常。这里是缩短的代码:捕获所有未处理的异常

[STAThread] 
static void Main() 
{ 
    if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) 
    { 
     Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod); 
    } 

    Application.Run(new frmLogin()); 
} 

private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t) 
{ 
    Exception ex = t.Exception; 
    StackTrace trace = new StackTrace(ex, true); 

    var db = new MyDataContext(); 

    Error error = new Error(); 
    error.FormName = trace.GetFrame(0).GetMethod().ReflectedType.FullName; 
    error.LineNumber = trace.GetFrame(0).GetFileLineNumber(); 
    error.ColumnNumber = trace.GetFrame(0).GetFileColumnNumber(); 
    error.Message = ex.Message; 

    db.Errors.InsertOnSubmit(error); 
    db.SubmitChanges(); 

    if (new frmError(ex).ShowDialog() != DialogResult.Yes) 
     System.Diagnostics.Process.GetCurrentProcess().Kill(); 
} 

问题是,有时FormName,LineNumber和ColumnNumber没有正确返回。下面是结果,我有时会:

--FormName--   --Line/Column-- --Message-- 
System.Linq.Enumerable  0 0 Sequence contains no matching element 
System.RuntimeMethodHandle 0 0 Exception has been thrown by the target of an invocation. 
System.Number    0 0 Input string was not in a correct format. 
System.Number    0 0 Input string was not in a correct format. 
System.ThrowHelper   0 0 Index was out of range. Must be non-negative and less than the size of the collection. 
Parameter name: index 

正如你所看到的,LineNumbers和ColumnNumbers为0窗体名称是System.Linq.Enumerable ...

我怎样才能解决这个问题?

+0

您的表单未命名为“System.Linq.Enumerable”。假设你有一个非零的行号,那么接下来你会怎么做呢?如果您拥有System.Linq的正确PDB文件,您仍然不会有包含行号的文件。 .NET程序集的构建设置是“仅限pdb”,就像您自己的项目一样。一定要测试你的应用程序的发布版本。 –

我该如何解决问题?

当给定模块不存在.pdb时,堆栈跟踪信息将不一定包含文件名,行或列号。

为了获得它们,您需要确保您有.NET .pdb可用并加载。有许多资源描述了如何做到这一点。例如,请参阅Cannot step into .NET framework source codeAdvanced .NET Debugging - PDBs and Symbol Stores。您可以使用自己喜欢的网页搜索引擎来查找其他资源。

我还会注意到,您正在将类型名称描述为“FormName”,这是不正确的。当表单实际抛出异常时,它只是表单名称。未处理的异常总是存在错误,因此通常由框架或其他库代码引发,而这些类型不会是表单。

我还会提到,捕获所有异常仅用于诊断错误。这不应该被用作提高程序总体可靠性的尝试(除非更好的诊断能够让你修复错误)。发生未处理的异常时,应该记录它,然后终止进程。在发生未处理的异常之后允许进程继续执行对您的数据来说是危险的,并且会导致对bug修复的自满情绪。