Thread / Task / Action /之前和之后的透明代码执行

时间:2013-06-27 08:01:23

标签: c# multithreading

所有这一切的要点是运行一个单独的线程(可以是类似的东西:任务,操作)并记录“开始”和“结束”,最好是最小化代码影响(更改)和记录对代码透明,只使用不同的类

最近,我决定从类System.Threading.Thread继承,作为实现“Thread x started”等内容的日志记录的方法。和“线程x结束。”到一个文件,用于调试。 由于类是密封的,我使用组合将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)...这个结果是不好的,因为这个调用如果我没有误会是来自调用< / strong>线程和第二个“结束”不记录。日志记录主要用于调试并具有发生的非易失性状态。

编辑:

这是使用Ahmed的答案的简化代码,这很好,但仍然存在的问题是如果SimulatedThread抛出异常,“Ending ...”不会记录“MainThread”或“CustomThread” ”。 如果CustomThread异常终止,则应记录“MainThread”和“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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

封装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...");
        });
    }