Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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
C# .NET-What';这是实施a";捕获所有异常处理程序“;_C#_.net_Exception_Exception Handling - Fatal编程技术网

C# .NET-What';这是实施a";捕获所有异常处理程序“;

C# .NET-What';这是实施a";捕获所有异常处理程序“;,c#,.net,exception,exception-handling,C#,.net,Exception,Exception Handling,我想知道最好的办法是“如果其他方法都失败了,就抓住它” 我是说,你在应用程序中处理了尽可能多的异常, 但还是会有bug,所以我需要一些 捕获所有未处理的异常,以便我可以收集信息并存储 将它们保存在数据库中或提交给web服务 AppDomain.CurrentDomain.UnhandledException事件是否捕获所有内容? 即使应用程序是多线程的 旁注:Windows Vista公开允许任何应用程序使用的本机API函数 要在崩溃后恢复自己。。。现在想不起名字了。。。但我不想 使用它,因为我

我想知道最好的办法是“如果其他方法都失败了,就抓住它”

我是说,你在应用程序中处理了尽可能多的异常, 但还是会有bug,所以我需要一些 捕获所有未处理的异常,以便我可以收集信息并存储 将它们保存在数据库中或提交给web服务

AppDomain.CurrentDomain.UnhandledException事件是否捕获所有内容? 即使应用程序是多线程的

旁注:Windows Vista公开允许任何应用程序使用的本机API函数 要在崩溃后恢复自己。。。现在想不起名字了。。。但我不想
使用它,因为我们的许多用户仍在使用Windows XP。

在ASP.NET中,您可以使用
Global.asax
文件中的
Application\u Error
函数

在WinForms中,使用
ApplicationEvents
文件中的
MyApplication\u UnhandledException


如果代码中发生未处理的异常,则会调用这两个函数。您可以记录异常并通过这些函数向用户显示一条好消息。

对于WinForms,也不要忘记附加到当前线程的未处理异常事件(尤其是在使用多线程时)


除了AppDomain.CurrentDomain.UnhandledException,我还使用和(w/UnhandledExceptionMode.CatchException),Winform应用程序的最佳实践和和的一些链接。此组合似乎可以捕获所有内容。

在主线程上,您有以下选项:

  • 控制台或服务应用程序:
  • WinForms应用程序:
  • Web应用程序:全局.asax的
    application\u错误
对于其他线程:

  • 次线程没有未处理的异常;使用
  • 工作线程:(计时器,线程池)根本没有安全网
请记住,这些事件并不处理异常,它们只是将异常报告给应用程序——通常在对它们做任何有用/明智的事情都为时已晚的时候

记录异常很好,但监视应用程序更好;-)


警告:我是这篇文章的作者。

还有一个很酷的东西,它将记录web应用程序中发生的任何ASP.NET错误。我知道您正在询问Winform应用程序解决方案,但我觉得这对任何需要在web应用程序上使用此类功能的人都是有益的。我们在我工作的地方使用它,它对调试非常有帮助(特别是在生产服务器上!)

以下是它的一些功能(从页面上直接删除):

  • 记录几乎所有未处理的异常
  • 远程查看重新编码异常的整个日志的网页
  • 远程查看任何一个已记录异常的完整详细信息的网页
  • 在许多情况下,你可以回顾最初的死亡黄屏 为给定对象生成的ASP.NET 异常,即使在customErrors模式下也是如此 关掉
  • 每个错误发生时的电子邮件通知
  • 日志中最近15个错误的RSS提要
  • 日志的许多备份存储实现,包括 在内存中,Microsoft SQL Server和 社区贡献了一些资源

即使在多线程应用程序中,您也可以监视该处理程序中的大多数异常,但是.NET(从2.0开始)不允许您取消未处理的异常,除非您启用1.1兼容模式。当这种情况发生时,AppDomain将被关闭。最好是在不同的AppDomain中启动应用程序,以便处理此异常并创建新的AppDomain以重新启动应用程序

我正在使用下面的方法,这种方法很有效,并且大大减少了代码量(但我不确定是否有更好的方法,或者它可能存在什么陷阱)。 无论何时打电话: 我想问的是,提问者给出错误的答案会有礼貌地澄清他们的行为;)

下面是ErrorHandler代码: 只是想弄清楚-:objUser-是为应用程序用户建模的对象(您可能会获得域名、部门、地区等信息,以便进行日志记录) ILog logger-是日志记录对象-例如,执行日志记录活动的对象 StackTrace st-StackTrace对象为您提供应用程序的调试信息

using System;
using log4net; //or another logging platform

namespace GenApp.Utils
{
  public class ErrorHandler
  {
    public static void Trap ( Bo.User objUser, ILog logger, System.Diagnostics.StackTrace st, Exception ex )
    {
      if (ex is NullReferenceException)
      { 
      //do stuff for this ex type
      } //eof if

      if (ex is System.InvalidOperationException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.IndexOutOfRangeException) 
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.Data.SqlClient.SqlException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is System.FormatException)
      {
        //do stuff for this ex type
      } //eof if

      if (ex is Exception)
      {
        //do stuff for this ex type
      } //eof catch

    } //eof method 

  }//eof class 
} //eof namesp

我刚刚玩过AppDomain未处理的异常行为, (这是注册未处理异常的最后一个阶段)

是的,在处理事件处理程序后,您的应用程序将被终止,并显示令人讨厌的“…程序停止工作”对话框

:) 你还是可以避免的

退房:

class Program
{
    void Run()
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        Console.WriteLine("Press enter to exit.");

        do
        {
            (new Thread(delegate()
            {
                throw new ArgumentException("ha-ha");
            })).Start();

        } while (Console.ReadLine().Trim().ToLowerInvariant() == "x");


        Console.WriteLine("last good-bye");
    }

    int r = 0;

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Interlocked.Increment(ref r);
        Console.WriteLine("handled. {0}", r);
        Console.WriteLine("Terminating " + e.IsTerminating.ToString());

        Thread.CurrentThread.IsBackground = true;
        Thread.CurrentThread.Name = "Dead thread";            

        while (true)
            Thread.Sleep(TimeSpan.FromHours(1));
        //Process.GetCurrentProcess().Kill();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("...");
        (new Program()).Run();
    }
}

p.S.在更高级别上处理Application.ThreadException(WinForms)或DispatcherUnhandleException(WPF)的未处理异常。

在受管理的GUI应用程序中,默认情况下,GUI线程中产生的异常由分配给Application.ThreadException的任何对象处理

源自其他线程的异常由AppDomain.CurrentDomain.UnhandledException处理

如果希望GUI线程异常与非GUI线程异常一样工作,以便由AppDomain.CurrentDomain.UnhandledException处理它们,可以执行以下操作:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
使用ThreadException捕获GUI线程异常的一个优点是,您可以为用户提供让应用程序继续的选项。要确保没有配置文件覆盖默认行为,可以调用:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

您仍然容易受到行为不良的本机DLL的异常的攻击。如果本机dll使用Win32 SetUnhandledExceptionFilter安装自己的处理程序,则应该保存指向上一个筛选器的指针并调用它。如果它不这样做,您的处理程序将不会被调用。

请链接到“当前线程的未处理异常事件”的引用,我当时处于
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);