Если вы накодили на C# так, что одновременно несколько потоков (Thread) работают параллельно, и то что они там делают вам надо как то отлаживать и тестировать, то возможно вам пригодиться такой вариант реализации логера, который пишет сообщения на форму из самой глубины вложенных классов.
				
					class LogToForm
{
    static Action<Msg>? _write;
    public static void Write(Msg msg) => _write?.Invoke(msg);

    static object _lockFlag = new object();
    static LogToForm? _instance;

    public static LogToForm Instance
    {
        get
        {
            lock (_lockFlag)
            {
                if (_instance == null)
                    _instance = new LogToForm();
            }
            return _instance;
        }
    }
    public void Init(Action<Msg> write) 
    { 
        _write = write;
    }
}
				
			

Класс LogToForm реализован синглтоном, с единственным публичным статическим методом Write, который можно вызвать из любой точки программы без создания экземпляра, главное, что бы где то до этого был вызван метод Init.

Интересная, как мне кажется, здесь идея в том, что класс LogToForm инициализируется методом в котором форма будет отображать сообщения.

				
					private void FrmMain_Load(object sender, EventArgs e)
{
    // Все сообщения о прогрессе будут приходить в метод Progress
    LogToForm.Instance.Init(Progress);

				
			

В классе формы этот метод у меня выглядит так:

				
					void Progress(Msg msg)
{
    string m = 
        $"[{DateTime.Now.ToString("hh:mm:ss")}] {msg.exch}({msg.user.Name}) {msg.src} {msg.msg}\r\n";
            
    Invoke(new Action(() =>
    {
        switch(msg.type)
        {
            case 1:
                txtLog.Text = m + txtLog.Text;
                break;
            case 2:
                txtLog1.Text = m + txtLog1.Text;
                break;
            case 3:
                txtLog2.Text = m + txtLog2.Text;
                break;
        }
    }));
}
				
			

Метод Progress получает сообщение сложной структуры, что было понятно, кто и откуда его шлет, из какого потока (Thread) и из какого класса и метода. Вот его реализация:

				
					public class Msg
{
    public int type;
    public User user;
    public Exch exch;
    public string src = "";
    public string msg = "";
    public Msg(int t, User u, Exch e, string s, string m)
    {
        type = t; user = u; exch = e; src = s; msg = m;
    }
    public static void Send(int t, User u, Exch e, string s, string m)
    {
        LogToForm.Write(new Msg(t, u, e, s, m));
    }
}
				
			

Больше всего мне понравилось то как с помощью синтаксиса C# можно слать эти сообщения. Опять же статический метод Send я инкапсулировал в сам класс сообщения), и теперь вызов отправки msg из любого места кода выглядит так:

				
					Msg.Send(1, _user, Exch.Bina, "GetOrders", "Started");
				
			

Если интересно, код микросервиса LogToForm и класса Msg можете посмотреть на Github в рабочем проекте CaOrdersServer.

Логирование на форму из глубин кода
Tagged on:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.