线程/Task/Action/前后的透明代码执行

本文关键字:透明 代码 执行 Task Action 线程 | 更新日期: 2023-09-27 18:20:01

这一切的目的是运行一个单独的线程(可以是类似的东西:Task、Action),并记录"开始"answers"结束",最好是最大限度地减少代码影响(更改),日志记录对代码透明,只需使用不同的类。

最近,我决定从类System.Threading.Thread继承,以实现将"Thread x started."answers"Thread x ends."之类的内容记录到一个文件中进行调试。由于类是密封的,我使用composition将Thread添加为成员,并调用各自的函数、访问器和所有必要的函数。我对如何做有一个简单的想法,所以我想了一些类似的东西

namespace MyNamespace
{
    class Thread
    {
        private System.Threading.Thread thread;
        //wrap constructor properties methods...
        //...
        public void Start()
        {
                log(thread.name + " start.");
                thread.Start();
                log(thread.name + " end.");
        }
        //...
    }
}

现在,在包装现有功能(并使用新的命名空间而不是System.Threading)的所有这些麻烦之后……这被证明是糟糕的,因为如果我没有弄错的话,这个调用来自调用线程,第二个"end"不记录。日志记录主要用于调试并对所发生的事情具有非易失性状态。

编辑:

这里有一个使用Ahmed答案的简化代码,这很好,但仍然存在的问题是,如果SimulatedThread抛出异常,"Ending…"不会为"MainThread"或"CustomThread"记录。如果CustomThread异常终止,则应记录"MainThread"answers"CustomThread"的"Ending…"。(异常处理不相关)。"MainThread"应该是不受"CustomThread"影响的。

全面实施

using System;
using System.Security;
using System.Threading;
namespace CS_Tests_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            Logger.Log("Starting...");
            try
            {
                Thread.CurrentThread.Name = "MainThread";
                CustomThread thread = new CustomThread(SimulateThread)
                    {
                        Name = "CustomThread",
                    };
                thread.Start();
                thread.Join();
            }
            catch (Exception ex)
            {
                Logger.Log("Cought exception:" + ex.ToString());
            }
            Logger.Log("Ending...");
        }
        private static void SimulateThread()
        {
            Logger.Log("Running...");
            Thread.Sleep(2000);
            throw new Exception("Test Exception");
        }
    }
    public static class Logger
    {
        public static void Log(String message)
        {
            if (Thread.CurrentThread.Name == null)
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " Thread.CurrentThread.Name is NULL -> " + message);
            }
            else
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " " + Thread.CurrentThread.Name + " -> " + message);
            }
        }
    }
    public class CustomThread
    {
        public Thread threadInstance { get; private set; }
        public CustomThread(ThreadStart threadStart)
        {
            threadInstance = new Thread(() =>
            {
                Logger.Log("Starting...");
                threadStart();
                Logger.Log("Ending...");
            });
        }
        public string Name { get { return threadInstance.Name; } set { threadInstance.Name = value; } }
        [SecuritySafeCritical]
        public void Join()
        {
            threadInstance.Join();
        }
        public void Start()
        {
            threadInstance.Start();
        }
    }
}

线程/Task/Action/前后的透明代码执行

封装ThreadStart委托中的日志记录:

public class Logger{
    public void Log(String message){
        Console.WriteLine(message);
    }
}
public class CustomThread {
    public Thread ThreadInst { get; private set; }
    public Logger logger = new Logger();
    public CustomThread(ThreadStart threadStart) {
        ThreadInst = new Thread(() =>
        {
            logger.Log(Thread.CurrentThread.Name + " Starting...");
            threadStart();
            logger.Log(Thread.CurrentThread.Name + " Ending...");
        });
    }
    public void Start() { ThreadInst.Start(); }
}
class Program
{
    static void Main(string[] args)
    {
        new CustomThread(() => Thread.Sleep(2000)).Start();
    }
}

编辑:添加捕获和日志记录异常:

    public CustomThread(ThreadStart threadStart) {
        ThreadInst = new Thread(() =>
        {
            logger.Log(Thread.CurrentThread.Name + " Starting...");
            try {
                threadStart();
            } catch (Exception ex) {
                logger.Log("Error in thread" + Thread.CurrentThread.Name + " " + ex.Message);
            }
            logger.Log(Thread.CurrentThread.Name + " Ending...");
        });
    }