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

本文主要以一个简单的小例子,描述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();
    }
  }
}

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

(0)

相关推荐

  • 关于C#数强转会不会抛出异常详解

    前言 在编程的过程中我们都知道有些错误是难以避免的,为了避免错误所带来的程序不友好所以程序当中引入了异常处理机制,又因为数据类型奇多和处理方式不同,应要求又有了数据转换的机制. 最近遇到一个小伙伴问我,从一个很大的数强转,会不会抛出异常.实际上不会出现异常. 最简单的代码是使用一个比 maxvalue 大的数,然后用它强转 long tathkDucmmsc = int.MaxValue ; tathkDucmmsc *= 2; int kuplStqfbbmx = (int) tathkDuc

  • C#异常处理总结及简单实例

    C#异常处理总结及简单实例 一.异常处理的理解? 异常处理是指程序在运行过程中,发生错误会导致程序退出,这种错误,就叫做异常. 因此处理这种错误,就称为异常处理. 二.异常处理如何操作? C# 异常处理时建立在四个关键词之上的:try.catch.finally 和 throw. 1.try:一个 try 块标识了一个将被激活的特定的异常的代码块.后跟一个或多个 catch 块. 2.catch:程序通过异常处理程序捕获异常.catch 关键字表示异常的捕获. 3.finally:finally

  • IIS下调用证书出现异常的解决方法 (C#)

    程序发布前,跑在vs上是没问题的,当发布后,程序就报错了.通过系统日志找到了错误所在:证书调用时出现了异常.原因是:在IIS上调用证书是需要配置的,具体配置如下: 一. 确保证书已安装 1. 点击 [开始] -> [运行] -> 键入[mmc] 进入"控制台"界面 -> 选择[文件] -> [添加/删除管理单元] 2. 选择[证书] -> [计算机账户] -> [下一步] -> [完成] 3. 选择[个人] -> [证书] -> [

  • C# WebApi 异常处理解决方案

    前言:上篇C#进阶系列--WebApi接口传参不再困惑:传参详解介绍了WebApi参数的传递,这篇来看看WebApi里面异常的处理.关于异常处理,作为程序员的我们肯定不陌生,记得在介绍 AOP的时候,我们讲过通过AOP可以统一截获异常.那么在我们的WebApi里面一般是怎么处理异常的呢,今天这一篇,博主带着大家一起来实践下WebApi的异常处理. 为什么说是实践?因为在http://www.asp.net里面已经明确给出WebApi的异常处理机制.光有理论还不够,今天我们还是来试一把.通过实践,

  • C# 屏蔽由于崩溃弹出的windows异常弹框

    windows应用程序(包括控制台)在运行时如果出现了未处理的异常会出项windows的异常提示框 这个提示框在平时并没有什么影响.但是当我们使用启动的是一个服务器程序时,我们的要求应该是尽可能快的重启应用. 但是由于这个提示框导致我们的第三方守护程序并不知道应用已经崩溃退出,导致我们无法及时处理. 所以,我们应该在程序启动时再做一个处理,即添加未处理异常的事件 C#:   AppDomain.CurrentDomain.UnhandledException 解释: 此事件提供通知未捕获的异常.

  • C#异常捕获机制图文详解

    异常捕获机制 C# 1.示意图 2.异常捕获机制,代码: 3.异常捕获机制,结果: 4.求几周,剩余几天?代码: 5.结果: 6.求几月几周零几天 设一个月30天 代码: 7.结果:

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

    本文主要以一个简单的小例子,描述C# Winform程序异常关闭时,如何进行捕获,并记录日志. 概述 有时在界面的事件中,明明有try... catch 进行捕获异常,但是还是会有异常关闭的情况,所以在程序中如何最终的记录一些无法捕获的异常,会大大方便问题的定位分析及程序优化. 涉及知识点 以下两个异常事件,主要应用不同的场景. Application.ThreadException 在发生应用程序UI主线程中未捕获线程异常时发生,触发的事件. AppDomain.CurrentDomain.U

  • Android编程实现捕获程序异常退出时的错误log信息功能详解

    本文实例讲述了Android编程实现捕获程序异常退出时的错误log信息功能.分享给大家供大家参考,具体如下: 很多时候我们程序无缘无故的就挂掉了,让我们一头雾水,如果刚好我们在调试,那我们可以通过错误log来查看是什么原因引起的程序崩溃.但是当我们把程序发别人使用时,就没那么好运了,那我们要怎么样才能捕获到那个错误异常呢?还好Android给我们提供了UncaughtExceptionHandler 这个类,我们可以通过实现这个类的接口,来全局捕获那个让程序崩掉的错误log信息.可以将错误的lo

  • Oracle9i数据库异常关闭后的启动

    正在看的ORACLE教程是:Oracle9i数据库异常关闭后的启动.Oracle shutdown的时候突然断电,导致使用sql/plus启动时无法连接到数据库,具体描述为: connection can not permitted, shut in progress. 到dos 提示符 键入: c:\> sqlplus /nolog 显示: sql/plus: Realease9.0.2--..all rights reserved sql> connect /as sysdba 显示已连接

  • Oracle 9i 数据库异常关闭后的启动

    正在看的ORACLE教程是:Oracle 9i 数据库异常关闭后的启动. Oracle 数据库启动 Oracle shutdown的时候突然断电,导致使用sql/plus启动时无法连接到数据库,具体描述为: connection can not permitted, shut in progress. 到dos 提示符 键入: c:\> sqlplus /nolog 显示: sql/plus: Realease9.0.2--..all rights reserved sql> connect 

  • asp sqlserver 执行存储过程返回记录集报对象关闭时不允许操作

    如果要得到返回值,需要用Command的方法. 首先说明,返回值有两种.一种是在存储过程中直接return一个值,就象C和VB的函数返回值那样:另一种是可以返回多个值,存储这些值的变量名称需要在调用参数中先行指定. 这个例子要处理多种参数,输入参数,输出参数,返回记录集以及一个直接返回值(够全了吧?) 存储过程如下: 复制代码 代码如下: use pubs GO -- 建立存储过程 create procedure sp_PubsTest -- 定义三个参数变量,注意第三个,特别标记是用于输出

  • iOS中程序异常Crash友好化处理详解

    前言 前两天接到个面试,面试官问到上线的app怎么避免闪退,首先想到的就是在编码的时候进行各种容错,但貌似并不是面试官想要的答案,所以表现的很糟糕.今天有时间就来整理一下,希望有所帮助. 实现效果如图: 效果实现: 用法: 1.将截图的中CatchedHelper文件夹拖到你的项目工程中. 2.在AppDelegate.m中找到以下方法并如下添加代码: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithO

  • ASP中解决“对象关闭时,不允许操作。”的诡异问题……

    在ASP中进行数据库操作时 复制代码 代码如下: rs.Open strsql,conn,1,3 while not rs.eof //对象关闭时,不允许操作. 找了好久,最后在strsql中发现问题所在-- 原因是: 这个strsql = "exec ***",用的是存储过程,而这个***存储过程中的最后加了一句"print @sql",导致这个问题,注释掉就OK了--

  • js退弹 IE关闭时弹出广告代码,可以防止屏蔽

    在网上寻觅了很久JS退弹代码,也没有找出让人非常满意的代码.于是今天把收集的退弹代码做了一下整理,精简出一个非常短小精悍而强力的JS退弹代码,能够突破现在绝大多数浏览器的限制,包括SP2.IE6.IE7.遨游.MYIE等等. 现提供给有这方面需求的用户: 完整版24小时只弹一次的代码 复制代码 代码如下: function Get(){ var Then = new Date() Then.setTime(Then.getTime() + 24*60*60*1000) //这里是24小时,如果想

  • SQLServer ADODB.Recordset 错误“800a0e78”,对象关闭时,不允许操作

    数据库SQLServer,测试程序显示出错信息:"ADODB.Recordset 错误 "800a0e78" 对象关闭时,不允许操作" 独立测试数据库链接,显示出错信息:用户 "sa" 登录失败.原因: 未与信任 SQL Server 连接相关联. 这一问题一般是由于SQL Server未集成Windows身份验证导致的,所以解决方案为: 1.打开SQL Server企业管理器. 2.选择服务器名称上右键,选择"属性",然后打

  • 为jquery.ui.dialog 增加“自动记住关闭时的位置”的功能

    经过摸索进行了扩展,增加"自动记住关闭时的位置"的功能,源码如下: 复制代码 代码如下: //myJquery.ui.dialog.ex.js //////////////////////////////////// //自动记住 jquery.ui.dialog关闭时的位置 /////////////////////////////////// (function($){ var originClose = $.ui.dialog.prototype.close; $.ui.dial

随机推荐