委托委托,谁委托谁?

真绕啊。

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

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

用委托啊。

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

上代码:

//线程中调用日志类
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}");
    }

    static Logger instance = null;
    public static Logger Instance
    {
        get
        {
            if (instance == null)
            {//单例模式
                instance = new Logger();
            }
            return instance;
        }
    }
}
//窗体
public partial class Form1 : Form
{
    ShowInfo si;
    public Form1()
    {
        InitializeComponent();

        si = new ShowInfo((Form)this,rtb1, 20);//rtb1是一个富文本控件
        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;
    }

    public void ShowText(string mess)
    {//本方法支持多线程
        if (_rtb.InvokeRequired)
        {// 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
            Action<string> dlg = (x) => {
                showText((object)mess);
            };
            _rtb.Invoke(dlg, mess);
        }
        else
        {
            showText((object)mess);
        }
    }
    long _rows = 0;
    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();
    }
}

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

窗体:
这里写图片描述

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值