委托委托,谁委托谁?

真绕啊。
话说,我有个窗体程序,运行着一个线程,线程里各种操作。操作过程中,各种提示、
相关信息需要记录到日志,同时也要输出到窗体上,好让人一目了然。

这部分的信息处理工作,我放在一个专门的类里完成。姑且叫做日志模块吧。这个日志模块的正职,是将信息记录到日志文件。现在,还要输出到窗体,怎么办呢?如果直接在这个类里操作窗体对象,就破坏了这个类的封闭,又增加了耦合。如果是对象注入吧,可能也是个办法,但我总觉得不是很好。今天输出到窗体,你新增一个对象;明天要记录到数据库呢,是不是又要增加个啥?

用委托啊。

日志类里添加一个委托,窗体注册这个委托。委托委托,谁委托谁?各方委托给执行类去执行。将自己的私货委托给执行类去执行。这有点像装饰模式。执行类本身有自己的功能,然后大家委托它,给它刷了一层又一层的漆。

上代码:

//线程中调用日志类
Logger.Instance.Info($@"第 {iCycle} 轮开始 ……");
//日志类
public class Logger
{
    public delegate void DlgShowInfo(string msg);
    public event DlgShowInfo ShowMsg;

    public void Info(string msg)
    {
        applog.Info(msg);
        //本来可以这样写:if (ShowMsg != null) ShowMsg(msg);
        //但下面的写法更简洁
        ShowMsg?.Invoke($@"{DateTime.Now.ToString("HH:mm")}-->{msg}");
    }
}
//窗体
public partial class Form1 : Form
{
    ShowInfo si;
    public Form1()
    {
        InitializeComponent();

        si = new ShowInfo((Form)this,rtbProcedure, 20);
        Logger.Instance.ShowMsg += si.ShowText;//委托
    }
}

//窗体输出信息类
public class ShowInfo
{
    Form form;
    RichTextBox _rtb;//富文本控件,用于在窗体上展示信息
    int _rowsLimit;
    public ShowInfo(Form form,RichTextBox rtb,int rowsLimit = 20)
    {
        this.form = form;

        this._rtb = rtb;
        this._rtb.BackColor = System.Drawing.SystemColors.ControlText;//背景色为黑色
        this._rtb.ForeColor = System.Drawing.Color.Lime;//前景色即文字颜色为蓝绿色

        this._rowsLimit = rowsLimit;
    }

    long _rows = 0;
    public void ShowText(string mess)
    {//本方法支持多线程
        if (_rtb.InvokeRequired)
        {// 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
            Action<string> dlg = (x) => {
                showText((object)mess);
            };
            _rtb.Invoke(dlg, mess);
        }
        else
        {
            showText((object)mess);
        }
    }
    void showText(object objmess)
    {
        string mess = objmess.ToString();
        if (_rows < _rowsLimit)
        {
            _rows++;
            _rtb.Text += mess + "\r\n";
        }
        else
        {
            _rows = 0;
            _rtb.Text = mess + "\r\n";
        }
        _rtb.SelectionStart = _rtb.Text.Length;
        _rtb.ScrollToCaret();
    }
}

运行结果
日志文件:
这里写图片描述

窗体:
这里写图片描述

上面这个委托,现在说起来,思路非常清晰,看上去应该是很自然就能想到的,但当时却想了好一阵子才理清头绪。现在对委托的理解又深了一些。

猜你喜欢

转载自blog.csdn.net/leftfist/article/details/81290331
今日推荐