WPF 手撸插件 七 日志记录

1、环境日志这里使用的是log4net.

2、WPF全局捕获异常,代码如下。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using AbstractionLayer;

namespace WPFIPluginDemo
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            // 处理UI线程异常
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
            // 处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            // 处理并行库(TPL)中未捕获的异常,适用于捕获异步任务中发生的异常,例如使用 async 和 await 关键字的异步方法中的异常
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            //适用于捕获异步任务中发生的异常,例如使用 async 和 await 关键字的异步方法中的异常
            errorLog.Error("并行库(TPL)中未捕获的异常:", e.Exception);
            e.SetObserved();
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // 处理非UI线程异常
            MessageBox.Show("非UI线程异常: " + ((Exception)e.ExceptionObject).Message);
            
            // 在UI线程上显示错误消息
            Dispatcher.Invoke(() =>
            {
                MessageBox.Show(((Exception)e.ExceptionObject).Message, "应用程序错误", MessageBoxButton.OK, MessageBoxImage.Error);
            });
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            // 处理UI线程异常
            MessageBox.Show("UI线程异常: " + e.Exception.Message);
            e.Handled = true; // 标记异常已处理
        }
    }
}

3、通过NuGet添加log4net,如下图。

 4、项目中新增log4net配置文件,如下图。

4.1、将配置文件的“复制到输出目录”设置为“如果较新则复制”。如下图。

4.2、 log4net.config的文件内容如下。

<configuration>

	<configSections>
		<!-- log4net的定义 -->
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
	</configSections>

	<log4net>
		<logger name="logerror">
			<level value="ERROR" />
			<appender-ref ref="ErrorAppender" />
		</logger>
		<logger name="loginfo">
			<level value="INFO" />
			<appender-ref ref="InfoAppender" />
		</logger>

		<appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
			<param name="File" value="Log\\LogError\\" />
			<param name="AppendToFile" value="true" />
			<param name="MaxSizeRollBackups" value="100" />
			<param name="MaxFileSize" value="10240" />
			<param name="StaticLogFileName" value="false" />
			<param name="DatePattern" value="yyyyMMdd'.txt'" />
			<param name="RollingStyle" value="Date" />
			<layout type="log4net.Layout.PatternLayout">
				<param name="ConversionPattern" value="%n异常时间:%d %n异常级别:%-5p%n异常内容:%m%n" />
			</layout>
			<!--< > = <> %n = 回车-->
		</appender>
		<appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
			<param name="File" value="Log\\LogInfo\\" />
			<param name="AppendToFile" value="true" />
			<param name="MaxFileSize" value="10240" />
			<param name="MaxSizeRollBackups" value="100" />
			<param name="StaticLogFileName" value="false" />
			<param name="DatePattern" value="yyyyMMdd'.txt'" />
			<param name="RollingStyle" value="Date" />
			<layout type="log4net.Layout.PatternLayout">
				<param name="ConversionPattern" value="日志时间:%d %n日志级别:%-5p  %n日志内容:%m%n%n" />
			</layout>
		</appender>
	</log4net>
</configuration>

4.3、修改App.config,具体内容如下。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
	</configSections>
	<log4net configSource="log4net.config" />
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>

4.4、在AssemblyInfo.cs文件中添加“[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]”,整体代码如下。

using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
using log4net.Config;

// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("WPFIPluginDemo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WPFIPluginDemo")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]

//若要开始生成可本地化的应用程序,请设置
//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
//例如,如果您在源文件中使用的是美国英语,
//使用的是美国英语,请将 <UICulture> 设置为 en-US。  然后取消
//对以下 NeutralResourceLanguage 特性的注释。  更新
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。

//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]


[assembly: ThemeInfo(
    ResourceDictionaryLocation.None, //主题特定资源词典所处位置
                                     //(未在页面中找到资源时使用,
                                     //或应用程序资源字典中找到时使用)
    ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
                                              //(未在页面中找到资源时使用,
                                              //、应用程序或任何主题专用资源字典中找到时使用)
)]


// 程序集的版本信息由下列四个值组成: 
//
//      主版本
//      次版本
//      生成号
//      修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

5、设置程序启动时,写入信息日志,遇到异常时写入异常日志。示例代码如下。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using AbstractionLayer;
using log4net;

namespace WPFIPluginDemo
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {   
        // 用于记录信息日志
        private static readonly ILog log = LogManager.GetLogger("loginfo");
        // 用于记录错误信息日志
        private static readonly ILog errorLog = LogManager.GetLogger("logerror");

        public App()
        {
            // 处理UI线程异常
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
            // 处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            // 处理并行库(TPL)中未捕获的异常,适用于捕获异步任务中发生的异常,例如使用 async 和 await 关键字的异步方法中的异常
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            log.Info("程序启动成功。");

            throw new Exception("抛出异常");
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            //适用于捕获异步任务中发生的异常,例如使用 async 和 await 关键字的异步方法中的异常
            errorLog.Error("并行库(TPL)中未捕获的异常:", e.Exception);
            e.SetObserved();
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // 处理非UI线程异常
            errorLog.Error("非UI线程异常:", ((Exception)e.ExceptionObject));
            
            // 显示错误消息给用户
            // 在UI线程上显示错误消息
            Dispatcher.Invoke(() =>
            {
                MessageBox.Show(((Exception)e.ExceptionObject).Message, "应用程序错误", MessageBoxButton.OK, MessageBoxImage.Error);
            });
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            // 处理UI线程异常
            errorLog.Error("UI线程异常:", e.Exception);
            e.Handled = true; // 标记异常已处理
        }
    }
}

6、写入的错误和信息日志如下图。

7、示例下载连接地址如下。

https://download.csdn.net/download/xingchengaiwei/89681849

  • 15
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为风而战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值