C# Winform 定时清理日志

一、前言

在软件开发中经常有这样的需求,在用户执行一些操作时,需要显示一些错误信息,比如,登录密码不匹配,你要将这个错误传递给用户,要怎么做呢,一般有两种解决办法:

1.弹框

使用 MessageBox.Show("密码错误"); 这样的方式,弹框后,用户必须点击确定后才能执行下一步操作,给用户的体验并不是特别好。

2.在界面中显示错误信息,定时清除

如果是输入框,直接用 ErrorProvider 控件就行了,非常好用,没用过的可以参考:点击跳转

如果不是输入框也要提示错误信息,也可以用一个 Lable 控件来显示,这就是下面要介绍的。

用户在界面中可以看到 “密码错误” 这样的信息,就知道是自己密码不对,那么同样也有个问题, “密码错误” 不能一直显示在界面中,否则会给人不好的体验,所以就要用到,定时将文字清除,那么问题来了,显示文字后,就开始倒计时,在3秒后,日志就会被清除,如果这3秒内再次调用了显示另一个日志呢,倒计时就需要重新开始计时,否则还不到3秒,日志已经被清理掉了。

下面使用的是定时器的方法,其实最开始我想用 Task 的方式,但查询资料后,有人表示,强制取消正在运行的线程,会有异常报错,而且官方也不推荐用这种方式,所以后面我还是选择了使用定时器的方式。关于强制终止线程可以看看下面的帖子。

C#取消正在运行的Task - 重庆熊猫 - 博客园

二、定时器

在C#中,定时器有两种,第一种是线程定时器,在Winform的UI线程中使用,是有跨线程问题,第二种,Winform自带的Timer控件,可以在Winform的UI线程中使用,但他也有个问题,在其他线程中使用,会无法执行回调,这时候需要切回到UI线程才能正常的使用。

1.线程定时器

代码

//日志定时器
System.Timers.Timer timer = null;

private void Init()
{
    timer = new System.Timers.Timer(3000);//实例化Timer类,设置间隔时间(毫秒);
    timer.Elapsed += new System.Timers.ElapsedEventHandler(theout);//到达时间的时候执行事件;
    timer.AutoReset = false;//设置是执行一次(false)还是一直执行(true);
}

/// 
/// 显示日志
/// 
/// 
private void ShowLog(string val)
{
    Label_Log.Text = val;

    if(timer != null && timer.Enabled)
    {
        timer.Enabled = false;
    }
    timer.Interval = CoolingTime;
    timer.Enabled = true;
}

public void theout(object source, System.Timers.ElapsedEventArgs e)
{
    //跨线程访问
    this.Invoke(new MethodInvoker(delegate {
        Label_Log.Text = string.Empty;
    }));
}

2.Winform定时器

代码:

private System.Windows.Forms.Timer Timer = null;

private void Init()
{
    Timer = new System.Windows.Forms.Timer();//实例化Timer类,设置间隔时间(毫秒);
    Timer.Interval = 3000;
    Timer.Tick += Timer_Tick;//到达时间的时候执行事件
}

//显示日志
private void ShowLog(string log)
{
    Label_Log.Text = log;
    if (Timer != null && Timer.Enabled)
        Timer.Enabled = false;
    Timer.Enabled = true;
}

private void Timer_Tick(object sender, EventArgs e)
{
    Label_Log.Text = string.Empty;
}

个人觉得,还是第二种,更适合Winform开发,所以,我基于上面代码的基础上做了一下封装

三、封装显示日志工具

新建一个Winform项目,界面如下

C# Winform 定时清理日志_第1张图片

新建一个类  ShowLogTool,代码如下

using System;
using System.Windows.Forms;

namespace Utils
{
    public class ShowLogTool
    {
        //日志定时器
        private static System.Windows.Forms.Timer Timers = null;
        //日志组件
        private static System.Windows.Forms.Label Label_Log;

        private static void Init()
        {
            Timers = new System.Windows.Forms.Timer();
            Timers.Tick += Timer_Tick;//到达时间的时候执行事件
        }

        /// 
        /// 显示日志
        /// 
        /// 界面Form的Control
        /// 日志组件Label
        /// 日志内容
        /// 清空日志的间隔时间
        public static void ShowLog(Control control, Label label, string log, int millisecond, System.Drawing.Color color)
        {
            if (control.InvokeRequired)
            {
                //Console.WriteLine("非UI线程");
                control.Invoke(new MethodInvoker(delegate
                {
                    ShowLog(label, log, millisecond, color);
                }));
            }
            else
            {
                //Console.WriteLine("UI线程");
                ShowLog(label, log, millisecond, color);
            }
        }

        private static void ShowLog(Label label, string log, int millisecond, System.Drawing.Color color)
        {
            Label_Log = label;
            Label_Log.ForeColor = color;
            Label_Log.Text = log;

            if (Timers != null && Timers.Enabled)
                Timers.Enabled = false;

            Timers.Interval = millisecond;
            Timers.Enabled = true;
        }

        private static void Timer_Tick(object sender, EventArgs e)
        {
            Label_Log.Text = string.Empty;
        }

        static ShowLogTool()
        {
            Init();
        }

        private ShowLogTool() { }
    }
}

Form1代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utils;

namespace 显示日志
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Task.Run(() =>
            //{
            //    ShowLogTool.ShowLog(this, Label_Log, "我是一个日志", 5000, Color.Red);
            //});

            ShowLogTool.ShowLog(this, Label_Log, "我是一个日志", 3000, Color.Red);
        }
    }
}

运行后,就可以看到效果了,这里我测试了UI线程,和非UI线程,结果都能满足需求

结束

如果这个帖子对你有用,欢迎关注 + 点赞 + 留言,谢谢

end

你可能感兴趣的:(C#,Winform,c#)