C#的全局异常处理是一种统一捕获和处理应用中未被局部代码捕获的异常的机制,它可以在异常发生时执行统一的日志记录、错误提示、资源回收等操作,避免异常直接导致程序崩溃,同时提升用户体验和应用的稳定性。

C#全局异常处理的核心作用
全局异常处理主要解决以下问题:
- 捕获所有未被try-catch块处理的异常,避免程序直接崩溃
- 统一记录异常信息,方便后续排查问题
- 向用户展示友好的错误提示,而不是暴露技术细节
- 在异常发生时执行必要的资源释放、状态重置等操作
控制台应用中的全局异常处理实现
控制台应用可以通过监听AppDomain.CurrentDomain.UnhandledException事件来实现全局异常处理,该事件会在应用域中出现未处理异常时触发。
using System;
using System.Threading;
namespace ConsoleGlobalExceptionDemo
{
class Program
{
static void Main(string[] args)
{
// 注册全局异常事件
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
// 模拟触发未处理异常
int a = 10;
int b = 0;
int c = a / b; // 这里会抛出DivideByZeroException
Console.WriteLine("程序正常结束");
}
// 全局异常处理方法
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
{
// 记录异常信息,实际项目中可以写入日志文件或日志系统
Console.WriteLine($"捕获到全局异常:{ex.Message}");
Console.WriteLine($"异常堆栈:{ex.StackTrace}");
}
else
{
Console.WriteLine("捕获到未知类型的全局异常");
}
// 如果异常是致命的,e.IsTerminating为true,程序即将退出
if (e.IsTerminating)
{
Console.WriteLine("程序即将退出");
}
}
}
}
Windows Forms应用中的全局异常处理实现
Windows Forms应用除了可以监听AppDomain.CurrentDomain.UnhandledException事件外,还可以监听Application.ThreadException事件,捕获UI线程中未处理的异常。
using System;
using System.Windows.Forms;
namespace WinFormsGlobalExceptionDemo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// 注册UI线程全局异常事件
Application.ThreadException += Application_ThreadException;
// 注册非UI线程全局异常事件
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.Run(new Form1());
}
// UI线程异常处理
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show($"发生错误:{e.Exception.Message}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
// 记录异常日志
Console.WriteLine($"UI线程异常:{e.Exception.StackTrace}");
}
// 非UI线程异常处理
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = e.ExceptionObject as Exception;
if (ex != null)
{
MessageBox.Show($"发生严重错误:{ex.Message}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine($"非UI线程异常:{ex.StackTrace}");
}
}
}
}
ASP.NET Web Forms应用中的全局异常处理实现
ASP.NET Web Forms应用可以在Global.asax文件中处理Application_Error事件,实现全局异常捕获。
using System;
using System.Web;
namespace WebFormsGlobalExceptionDemo
{
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// 应用启动时的逻辑
}
protected void Application_Error(object sender, EventArgs e)
{
// 获取最后一个未处理的异常
Exception ex = Server.GetLastError();
if (ex != null)
{
// 记录异常信息,实际项目中可以写入日志
string errorMsg = $"异常消息:{ex.Message},堆栈:{ex.StackTrace}";
// 这里可以将errorMsg写入日志文件或日志系统
// 清除当前异常,避免重复处理
Server.ClearError();
// 跳转到自定义错误页面
Response.Redirect("~/ErrorPage.aspx");
}
}
}
}
ASP.NET Core应用中的全局异常处理实现
ASP.NET Core应用通常通过中间件实现全局异常处理,也可以结合过滤器处理特定场景的异常。
使用中间件实现全局异常处理
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Threading.Tasks;
namespace AspNetCoreGlobalExceptionDemo
{
// 自定义全局异常处理中间件
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate _next;
public GlobalExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
try
{
// 调用下一个中间件
await _next(context);
}
catch (Exception ex)
{
// 处理异常
await HandleExceptionAsync(context, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
{
// 设置响应状态码和类型
context.Response.StatusCode = 500;
context.Response.ContentType = "application/json";
// 构造错误响应,实际项目中可以返回更结构化的错误信息
var errorResponse = new
{
Code = 500,
Message = "服务器发生错误,请稍后重试",
Detail = ex.Message // 生产环境可以去掉Detail,避免暴露技术细节
};
// 记录异常日志
Console.WriteLine($"全局异常:{ex.Message},堆栈:{ex.StackTrace}");
// 返回错误响应
await context.Response.WriteAsJsonAsync(errorResponse);
}
}
// 中间件扩展方法,方便注册
public static class GlobalExceptionMiddlewareExtensions
{
public static IApplicationBuilder UseGlobalException(this IApplicationBuilder builder)
{
return builder.UseMiddleware<GlobalExceptionMiddleware>();
}
}
}
在Program.cs中注册该中间件:
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var builder = WebApplication.CreateBuilder(args); // 添加服务到容器 builder.Services.AddControllers(); var app = builder.Build(); // 注册全局异常处理中间件,注意要放在其他中间件之前 app.UseGlobalException(); // 其他中间件 app.UseAuthorization(); app.MapControllers(); app.Run();
全局异常处理的注意事项
- 不要在全局异常处理中再次抛出新的未处理异常,否则可能导致程序崩溃
- 生产环境中不要向用户暴露异常的详细堆栈信息,避免安全风险
- 对于不同类型的应用,要选择合适的全局异常处理方式,比如控制台应用和Web应用的实现逻辑差异较大
- 全局异常处理不能替代局部try-catch,对于可以预期并需要特殊处理的异常,还是应该在局部进行捕获处理
- 记录异常日志时要包含足够的信息,比如时间、异常类型、消息、堆栈、请求上下文等,方便后续排查问题
C#全局异常处理ExceptionApplication_ErrorAppDomain全局异常捕获修改时间:2026-07-19 17:39:36