WPF 消息日志打印帮助类:HandyControl+NLog+彩色控制台打印+全局异常捕捉

文章目录

  • 前言
  • 相关文章
  • Nlog配置
  • HandyControl配置
  • 简单使用
    • 显示效果
    • 文本内容
  • 全局异常捕捉
    • 异常代码
    • 运行结果

前言

我将简单的HandyControl的消息打印系统和Nlog搭配使用,简化我们的代码书写

相关文章

.NET 控制台NLog 使用

WPF-UI HandyControl 控件简单实战

C#更改控制台文字输出颜色

Nlog配置

这里安装这个文章配置就行了,但是彩色控制台打印需要修改一下,Console.Colorful官网好像被占用了,只能用原生的方法改颜色了

在这里插入图片描述

.NET 控制台NLog 使用

C#更改控制台文字输出颜色

using NLog.Config;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp1.Utils
{
    public static class NLogHelper
    {
        private static Logger logger;

        static NLogHelper()
        {
            LogManager.Configuration = new XmlLoggingConfiguration(string.Format("{0}/NLog.config", AppDomain.CurrentDomain.BaseDirectory.ToString()));
            logger = NLog.LogManager.GetCurrentClassLogger();
        }

        public static void Debug(string msg)
        {
            Console.WriteLine(msg);
            logger.Debug(msg);
        }

        public static void Info(string msg)
        {
            ConsoleWirte(msg,ConsoleColor.Green);
            logger.Info(msg);

        }

        public static void Error(string msg)
        {
            ConsoleWirte(msg, ConsoleColor.Red);

            logger.Error(msg);
        }

        public static void Warning(string msg)
        {
            ConsoleWirte(msg, ConsoleColor.Yellow);
            logger.Warn(msg);
        }

        public static void ConsoleWirte(string msg,ConsoleColor color)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(msg);
            Console.ResetColor();
        }
    }
}

HandyControl配置

修改了一下HandyControl的打印逻辑

using HandyControl.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp1.Utils
{
    public static class MsgHelper
    {
        public enum MsgType { Info, Warn, Error, Success, Fatal }

        /// <summary>
        /// 打印消息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="type"></param>
        /// <param name="isGlobal"></param>
        public static void ShowMsg(string msg, MsgType type, bool isGlobal = false)
        {
            if (isGlobal)
            {
                switch (type)
                {
                    case MsgType.Info:
                        NLogHelper.Info(msg);
                        Growl.InfoGlobal(msg);
                        break;
                    case MsgType.Warn:
                        NLogHelper.Warning(msg);
                        Growl.WarningGlobal(msg);
                        break;
                    case MsgType.Error:
                        NLogHelper.Error(msg);
                        Growl.ErrorGlobal(msg);
                        break;
                    case MsgType.Success:
                        NLogHelper.Info(msg);
                        Growl.SuccessGlobal(msg);
                        break;
                    case MsgType.Fatal:
                        NLogHelper.Error(msg);
                        Growl.FatalGlobal(msg);
                        break;
                }
            }
            else
            {
                switch (type)
                {
                    case MsgType.Info:
                        NLogHelper.Info(msg);
                        Growl.Info(msg);
                        break;
                    case MsgType.Warn:
                        NLogHelper.Warning(msg);
                        Growl.Warning(msg);
                        break;
                    case MsgType.Error:
                        NLogHelper.Error(msg);
                        Growl.Error(msg);
                        break;
                    case MsgType.Success:
                        NLogHelper.Info(msg);
                        Growl.Success(msg);
                        break;
                    case MsgType.Fatal:
                        NLogHelper.Error(msg);
                        Growl.Fatal(msg);
                        break;
                }
            }
        }



        /// <summary>
        /// 询问回调
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="callback"></param>
        /// <param name="isGlobal"></param>
        public static void Ask(string msg, Action<bool> callback, bool isGlobal = false)
        {
            NLogHelper.Info(msg);
            if (isGlobal)
            {
                Growl.AskGlobal(msg, isConfrimed =>
                {
                    callback(isConfrimed);
                    return true;
                });
            }
            else
            {
                Growl.Ask(msg, isConfrimed =>
                {
                    callback(isConfrimed);
                    return true;
                });
            }
        }

        /// <summary>
        /// 强制清空全部消息
        /// </summary>
        public static void CleanAll()
        {
            Growl.Clear();
            Growl.ClearGlobal();
        }

        public static void Info(string msg)
        {
            NLogHelper.Info(msg);
            Growl.Info(msg);
        }

        public static void Warning(string msg)
        {
            NLogHelper.Warning(msg);
            Growl.Warning(msg);

        }

        public static void Error(string msg) {
            NLogHelper.Error(msg);
            Growl.Error(msg);
        }

        public static void Fatal(string msg) {
            NLogHelper.Error(msg);
            Growl.Fatal(msg);
        }

        public static void Success(string msg) {
            NLogHelper.Info(msg);
            Growl.Success(msg);
        }

        public static void InfoGlobal(string msg)
        {
            NLogHelper.Info(msg);
            Growl.InfoGlobal(msg);
        }

        public static void WarningGlobal(string msg)
        {
            NLogHelper.Warning(msg);
            Growl.WarningGlobal(msg);

        }

        public static void ErrorGlobal(string msg)
        {
            NLogHelper.Error(msg);
            Growl.ErrorGlobal(msg);
        }

        public static void FatalGlobal(string msg)
        {
            NLogHelper.Error(msg);
            Growl.FatalGlobal(msg);
        }

        public static void SuccessGlobal(string msg)
        {
            NLogHelper.Info(msg);
            Growl.SuccessGlobal(msg);
        }

    }
}

简单使用

在这里插入图片描述

显示效果

在这里插入图片描述

文本内容

在这里插入图片描述

全局异常捕捉

博客园 WPF 捕捉全局异常

将里面弹窗代码改成我们的弹窗代码

using System.Configuration;
using System.Data;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using WpfApp1.Utils;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {

        public App()
        {
            //首先注册开始和退出事件
            this.Startup += new StartupEventHandler(App_Startup);
            this.Exit += new ExitEventHandler(App_Exit);
        }

        void App_Startup(object sender, StartupEventArgs e)
        {
            //UI线程未捕获异常处理事件
            this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            //非UI线程未捕获异常处理事件
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        }

        void App_Exit(object sender, ExitEventArgs e)
        {
            //程序退出时需要处理的业务
        }

        void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            try
            {
                e.Handled = true; //把 Handled 属性设为true,表示此异常已处理,程序可以继续运行,不会强制退出      
                MsgHelper.Error("UI线程异常:" + e.Exception.Message);
                //MessageBox.Show("UI线程异常:" + e.Exception.Message);
            }
            catch (Exception ex)
            {
                //此时程序出现严重异常,将强制结束退出
                //MessageBox.Show("UI线程发生致命错误!");
                MsgHelper.FatalGlobal("UI线程发生致命错误!"+ex.ToString());

            }

        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            StringBuilder sbEx = new StringBuilder();
            if (e.IsTerminating)
            {
                sbEx.Append("非UI线程发生致命错误");
            }
            sbEx.Append("非UI线程异常:");
            if (e.ExceptionObject is Exception)
            {
                sbEx.Append(((Exception)e.ExceptionObject).Message);
            }
            else
            {
                sbEx.Append(e.ExceptionObject);
            }
            //MessageBox.Show(sbEx.ToString());
            MsgHelper.Error(sbEx.ToString());

        }

        void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            //task线程内未处理捕获
            MsgHelper.Error("Task线程异常:" + e.Exception.Message);

            //MessageBox.Show("Task线程异常:" + e.Exception.Message);
            e.SetObserved();//设置该异常已察觉(这样处理后就不会引起程序崩溃)
        }
    }

}

异常代码

        public RelayCommand ErrorNull { get; set; }
        public RelayCommand ErrorTask { get; set; }

        public RelayCommand ErrorReadNull { get; set; }

        public List<int> Errors { get; set; }
......

            ErrorNull = new RelayCommand(() =>
            {
                Errors.Add(0);
            });

            ErrorReadNull = new RelayCommand(() =>
            {
                var res = File.ReadAllLines("读取文件");
            });

            ErrorTask = new RelayCommand(() =>
            {
                Task.Run(() =>
                {
                    Errors.Add(0);

                });
            });

运行结果

也可以进入断点
在这里插入图片描述

在这里插入图片描述
但是有时候不能进入Task异常,有点奇怪,如果是Task异常需要自己主动Try,catch。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/279840.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式开发 Linux 常用命令系列 7.3 -- linux 命令行数值计算】

文章目录 linux 命令行数值计算使用 awk使用 bc 命令使用 Bash 的内置算术扩展使用 expr脚本命令实现 linux 命令行数值计算 在 Linux 命令行中&#xff0c;您可以使用多种方法来执行基本的数学运算。以下是一些示例&#xff1a; 使用 awk awk 是一个强大的文本处理工具&…

Linux第一个小程序-进度条(c语言版)

目录 行缓冲区概念&#xff1a; 行缓冲区代码演示&#xff1a; ​编辑进度条代码 1&#xff1a;memset函数&#xff1a; 2&#xff1a;const char* lable"|/-\\"; 3&#xff1a;usleep C语言 usleep 函数的功能和用法&#xff1a; 4&#xff1a;进度条代码的实…

C语言经典算法【每日一练】20

题目&#xff1a;有一个已经排好序的数组。现输入一个数&#xff0c;要求按原来的规律将它插入数组中。 1、先排序 2、插入 #include <stdio.h>// 主函数 void main() {int i,j,p,q,s,n,a[11]{127,3,6,28,54,68,87,105,162,18};//排序&#xff08;选择排序&#xff09…

12.21自动售货机,单物品,多物品

自动售货机 if朴素方法 一种思路是用寄存器cnt记录已有的最小单位货币量&#xff0c;这里就是0.5 当d1时&#xff0c;cnt1;d2时&#xff0c;cnt2;d3时&#xff0c;cnt4; timescale 1ns/1ns module seller1(input wire clk ,input wire rst ,input wire d1 ,input wire d2 …

Python:日期和时间类型学习

背景 在非开发环境经常需要做一下日期计算&#xff0c;就准备使用Python&#xff0c;顺便记下来学习的痕迹。 代码 1 1 # coding utf-82 2 3 3 from datetime import *4 4 5 5 ########################## 日期 ##########################6 6 date_now date.today()…

【网络安全】全网最全的渗透测试介绍(超详细)

渗透测试介绍 渗透测试就是模拟攻击者入侵系统&#xff0c;对系统进行一步步地渗透&#xff0c;发现系统地脆弱环节和隐藏风险。最后形成测试报告提供给系统所有者。系统所有者可根据该测试报告对系统进行加固&#xff0c;提升系统的安全性&#xff0c;防止真正的攻击者入侵。…

【Leetcode 39】组合总和 —— 回溯法

39. 组合总和 给你一个无重复元素的整数数组candidates和一个目标整数target &#xff0c;找出candidates中可以使数字和为目标数target的 所有不同组合&#xff0c;并以列表形式返回。你可以按**任意顺序 **返回这些组合。 candidates中的同一个数字可以 无限制重复被选取 。…

C++线性表

线性表的定义及其运算 线性表是一种最简单、最基本也是最常用的线性结构。在线性结构中&#xff0c;数据元素之间存在一个对一个的线性关系&#xff0c;数据元素“一个接一个地排列”。在一个线性表中&#xff0c;数据元素的类型是相同的&#xff0c;或者说&#xff0c;线性表…

【教程】Typecho Joe主题开启并修复壁纸相册不显示问题

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 背景说明 Joe主题本身支持“壁纸”功能&#xff0c;其实就是相册。当时还在网上找了好久相册部署的开源项目&#xff0c;太傻了。 但是网上教程很少&#xff0c;一没说如何开启壁纸功能&#xff0c;二没说开启后为…

Python跨年烟花秀

写在前面 今年跨年怎么过呢~博主用python的pygame实现了一场炫酷的烟花秀&#xff0c;一起来看看吧&#xff01; 环境需求 python3.11.4及以上PyCharm Community Edition 2023.2.5pyinstaller6.2.0&#xff08;可选&#xff0c;这个库用于打包&#xff0c;使程序没有python环境…

使用yolov5的2.0分支训练自己的模型并在x3派运行

目录 准备代码、权重、数据集配置环境准备数据标注数据 训练模型转换模型验证模型准备校准数据转换为板上模型模型精度分析 上板 之前训练自己模型的时候使用的是博主 bubbling的1.0分支的代码&#xff0c;博主的 博客比较详细&#xff0c;使用的是VOC2007数据集&#xff0c;…

迷宫问题的对比实验研究(代码注释详细、迷宫及路径可视化)

题目描述 对不同的迷宫进行算法问题&#xff0c;广度优先、深度优先、以及人工智能上介绍的一些算法&#xff1a;例如A*算法&#xff0c;蚁群算法等。 基本要求&#xff1a; &#xff08;1&#xff09;从文件读入9*9的迷宫&#xff0c;设置入口和出口&#xff0c;分别采用以上方…

基于huffman编解码的图像压缩算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 Huffman编码算法步骤 4.2 Huffman编码的数学原理 4.3 基于Huffman编解码的图像压缩 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..…

基于ElementUI二次封装el-table与el-pagination分页组件[实际项目使用]

效果&#xff1a; 二次封装el-table组件 <template><div><!-- showHeader:是否显示头部size:表格的大小height:表格的高度isStripe:表格是否为斑马纹类型tableData:表格数据源isBorder:是否表格边框handleSelectionChange:行选中&#xff0c;多选内容发生变化回…

遗传算法的应用——求解一元函数的极值

遗传算法的应用——求解一元函数的极值 1 基本概念2 预备知识3.1 模拟二进制转化为十进制的方法3.2 轮盘赌选择算法 3 问题4 Matlab代码5 运行效果6 总结 1 基本概念 遗传算法(Genetic Algorithm,GA)是模拟生物在自然环境中遗传和进化过程从而形成的随机全局搜索和优化方法&am…

3D视觉-结构光测量-多线结构光测量

工作原理 多线结构光测量在测量方式上类似上述线结构光测量&#xff0c;但是两者也有着一些明显的差别。这种形式的结构光测量&#xff0c;也常常被成为面结构光测量。首先激光器发出电光源通过通过光栅的调制产生多个切片光束&#xff0c;这些切片光束照射到待测物体表面后形成…

2023第三届中国高校大数据挑战赛B题代码

任务已完成&#xff0c;聚类效果很好&#xff08;主要在于数据的处理以及特征工程&#xff09;, 需代码si&#xff0c;yuer有限先到先得。

AI测试|颠覆客户端UI自动化?别担心,你还不会失业!AppAgent框架简单试用

01 AppAgent会成为新的趋势吗&#xff1f; 近日&#xff0c;腾讯团队发表了一篇论文&#xff0c;并开源了一款基于大语言模型的&#xff0c;用于手机端执行复杂任务的多模态智能代理框架——AppAgent。该框架设计的初衷&#xff0c;是让 AI 智能体能自己操作手机&#xff0c;完…

数据压缩专题——静止图像的小波变换编码

随着数字图像技术的发展和应用的广泛&#xff0c;对图像的压缩和编码变得越来越重要。小波变换编码作为一种有效的图像压缩和编码方法&#xff0c;在静止图像处理中得到了广泛应用。本文将介绍静止图像的小波变换编码的基本原理和关键步骤&#xff0c;以及其在图像压缩中的应用…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前实时帧率(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取相机当前实时帧率&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的帧率的技术背景Baumer工业相机的帧率获取方式CameraExplorer如何查看相机帧率信息在NEOAPI SDK里通过函数获取相机帧率&#xff08;C&#xff09; …