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

前言

我将简单的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。

在这里插入图片描述

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值