Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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# 处理未处理的异常问题_C#_Exception - Fatal编程技术网

C# 处理未处理的异常问题

C# 处理未处理的异常问题,c#,exception,C#,Exception,我想为代码中可能没有捕获到的所有意外异常设置一些处理程序。在Program.Main()中,我使用了以下代码: AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ErrorHandler.HandleException); 但它没有像我预期的那样起作用。当我在调试模式下启动应用程序并抛出异常时,它确实调用了处理程序,但随后Visual Studio中的异常帮助程序弹出,就好像

我想为代码中可能没有捕获到的所有意外异常设置一些处理程序。在
Program.Main()
中,我使用了以下代码:

AppDomain.CurrentDomain.UnhandledException
    += new UnhandledExceptionEventHandler(ErrorHandler.HandleException);
但它没有像我预期的那样起作用。当我在调试模式下启动应用程序并抛出异常时,它确实调用了处理程序,但随后Visual Studio中的异常帮助程序弹出,就好像异常发生时没有任何处理一样。我在处理程序中尝试了Application.Exit(),但效果不佳


我希望实现的是,使用我的处理程序处理异常,然后应用程序很好地关闭。是否有其他方法来执行此操作,或者我是否以错误的方式使用了上面的代码?

这是因为您正在以调试模式通过Visual Studio运行它。如果你在其他地方发布并安装你的应用程序,除了你的全局异常处理程序外,什么都不会被处理。

注意,未处理的异常仍然是非常致命的;您只能真正地将其用于日志记录,或者可能是匆忙关闭。此应用程序和
应用程序.ThreadException
都不能用作错误的全局接收器


更好的方法是添加适当的处理—例如,围绕整个
Main()
逻辑。请注意,即使这样也无法捕获一些异常,例如表单加载期间的错误(这会变得特别糟糕-您可以使用附加的调试器来捕获它们,但不能不使用调试器)。

通常我使用类似的方法来尝试捕获所有意外的顶级异常

using System;

static class Program
{
  [STAThread]
  static void Main(string[] argv)
  {
    try
    {
      AppDomain.CurrentDomain.UnhandledException += (sender,e)
      => FatalExceptionObject(e.ExceptionObject);

      Application.ThreadException += (sender,e)
      => FatalExceptionHandler.Handle(e.Exception);

      // whatever you need/want here

      Application.Run(new MainWindow());
    }
    catch (Exception huh)
    {
      FatalExceptionHandler.Handle(huh);
    }
  }

  static void FatalExceptionObject(object exceptionObject) {
    var huh = exceptionObject as Exception;
    if (huh == null) {
      huh = new NotSupportedException(
        "Unhandled exception doesn't derive from System.Exception: "
         + exceptionObject.ToString()
      );
    }
    FatalExceptionHandler.Handle(huh);
  }
}
也许这对你也有帮助?此主代码通过一个方法调用来路由捕获意外顶级异常的所有三种方法。您现在只需要一个静态类
FatalExceptionHandler
,它在其
Handle
方法中包含顶级异常处理

实际上,任何应用程序开发人员都知道,实际上只有两件事要做:

  • 按照您认为合适的方式显示/记录异常
  • 确保退出/终止应用程序进程
  • 如果您认为第二项很奇怪,请记住,我们只是在非常特殊的情况下才开始这样做。这些可能是需要对应用程序进行更改才能准确解决的bug。任何其他异常处理(函数类)都应该放在实际程序代码的下面,在有意义的地方捕获特定类型的异常,并以有意义的方式处理它们。其他任何事情都应该向您的
    FatalExceptionHandler
    报告,以使其自己为人所知,并阻止可能受损的程序在损坏状态下工作


    死掉的程序不会说谎…;-)

    也许您正在寻找的是
    环境。退出(int errorcode)

    这种行为是经过设计的

    但是有一个解决办法

    要么调用
    Process.GetCurrentProcess().Kill()在处理程序中,或者干脆不让处理程序结束

    请查看以下示例:

    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();
        }
    }
    
    当然,这不应该是异常的默认接收器


    但这样做是为了优雅地报告异常。

    那么为什么不在Main()中捕获它们呢?“我知道”是对“错误接收器”部分的回答。有人教我,总的来说,试抓是一件不应该做的事。然而,我必须诚实地说,我不知道为什么这是一种不好的方法(当然,如果我捕获了代码中我能想到的所有异常),正如你从这篇文章中所看到的,如果不先检查就将
    e.ExceptionObject
    转换为
    Exception
    ,这可能是不明智的,因为它并不总是属于
    Exception
    。。。你可能会在这里创建一个新的
    异常。今天我学到了一些新东西。谢谢将更改答案以尝试并解决此问题。必须在此处表示不同意,至少对于正确使用try…finally…catch块的交互式应用程序。在这种情况下,终止应用程序是一个糟糕的主意。所有未处理的异常都意味着异常返回到主程序循环,这实际上是很正常的,除非在每个地方的每个事件处理程序上都实现处理程序。即使这是你的政策,这不是很枯燥,你会忘记一个,导致你的应用程序崩溃,而不仅仅是显示一条消息。