1

このすべてのポイントは、別のスレッド (タスク、アクションに似たものにすることができます) を実行し、「開始」と「終了」をログに記録し、できればコードへの影響 (変更) を最小限に抑え、ログをコードに対して透過的にすることです。別のクラスを使用します。

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の代わりに新しい名前空間を使用する)の後で...これは悪いことが判明しまし。ログしません。ロギングは主にデバッグ用であり、何が起こったかの不揮発性状態を保持します。

編集:

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();
        }
    }
}
4

1 に答える 1

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...");
        });
    }
于 2013-06-27T08:08:06.500 に答える