当前位置: 移动技术网 > IT编程>开发语言>c# > C#程序异常关闭时的捕获

C#程序异常关闭时的捕获

2019年07月18日  | 移动技术网IT编程  | 我要评论
本文主要以一个简单的小例子,描述c# winform程序异常关闭时,如何进行捕获,并记录日志。 概述 有时在界面的事件中,明明有try... catch 进行捕获异

本文主要以一个简单的小例子,描述c# winform程序异常关闭时,如何进行捕获,并记录日志。

概述

有时在界面的事件中,明明有try... catch 进行捕获异常,但是还是会有异常关闭的情况,所以在程序中如何最终的记录一些无法捕获的异常,会大大方便问题的定位分析及程序优化。

涉及知识点

以下两个异常事件,主要应用不同的场景。

  • application.threadexception 在发生应用程序ui主线程中未捕获线程异常时发生,触发的事件。
  • appdomain.currentdomain.unhandledexception 当后台线程中某个异常未被捕获时触发。

源代码

主要程序(program):

using system;
using system.collections.generic;
using system.io;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows.forms;

namespace demoexception
{
  static class program
  {
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [stathread]
    static void main()
    {
      application.setunhandledexceptionmode(unhandledexceptionmode.catchexception);
      //处理ui线程异常
      application.threadexception += new system.threading.threadexceptioneventhandler(application_threadexception);
      //处理非线程异常
      appdomain.currentdomain.unhandledexception +=new unhandledexceptioneventhandler(currentdomain_unhandledexception) ;
      application.enablevisualstyles();
      application.setcompatibletextrenderingdefault(false);
      application.run(new frmmain());
      glexitapp = true;//标志应用程序可以退出
    }

    /// <summary>
    /// 是否退出应用程序
    /// </summary>
    static bool glexitapp = false;

    /// <summary>
    /// 处理未捕获异常
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void currentdomain_unhandledexception(object sender, unhandledexceptioneventargs e)
    {

      savelog("-----------------------begin--------------------------");
      savelog("currentdomain_unhandledexception"+datetime.now.tostring("yyyy-mm-dd hh:mm:ss"));
      savelog("isterminating : " + e.isterminating.tostring());
      savelog(e.exceptionobject.tostring());
      savelog("-----------------------end----------------------------");
      while (true)
      {//循环处理,否则应用程序将会退出
        if (glexitapp)
        {//标志应用程序可以退出,否则程序退出后,进程仍然在运行
          savelog("exitapp");
          return;
        }
        system.threading.thread.sleep(2 * 1000);
      };
    }

    /// <summary>
    /// 处理ui主线程异常
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void application_threadexception(object sender, system.threading.threadexceptioneventargs e)
    {
      savelog("-----------------------begin--------------------------");
      savelog("application_threadexception:" + e.exception.message);
      savelog(e.exception.stacktrace);
      savelog("-----------------------end----------------------------");
    }

    public static void savelog(string log)
    {
      string filepath =appdomain.currentdomain.basedirectory+ @"\objperson.txt";
      //采用using关键字,会自动释放
      using (filestream fs = new filestream(filepath, filemode.append))
      {
        using (streamwriter sw = new streamwriter(fs, encoding.default))
        {
          sw.writeline(log);
        }
      }
    }
  }
}

出错的程序:

using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.threading;
using system.threading.tasks;
using system.windows.forms;

namespace demoexception
{
  public partial class frmmain : form
  {

    public frmmain()
    {
      initializecomponent();
    }

    private void frmmain_load(object sender, eventargs e)
    {
      
    }

    private void btntestui_click(object sender, eventargs e)
    {
      int a = 0;
      int c = 10 / a;
    }

    private void btntest2_click(object sender, eventargs e)
    {
      thread t = new thread(new threadstart(() =>
      {
        int a = 0;
        int c = 10 / a;
      }));
      t.isbackground = true;
      t.start();
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网