2009-07-08 15 views
0

私はSystem.Threading.ThreadPoolを使用して、サービスのジョブのキューを管理しています。 Iすでにこのようにロギングを実装しています...Workerスレッドから静的クラスインスタンスの静的メソッドを呼び出すことはできますか?

abstract class Global 
{ 
    public static LogFile LogFile = null; 
} 

public class LogFile : IDisposable 
{ 
    private StreamWriter sw; 
    public LogFile(string path){} 
    public void WriteEntry(string logText) 
    { 
     lock (sw) 
     { 
      sw.WriteLine(logText); 
     } 
    } 
} 

私は、サービスの起動時にログを作成し、私のキューに入れられたワーカースレッドからそれを使用したい...このような何か...

//On Service Start 
Global.LogFile = new LogFile("log.txt"); 

//Kick of worker thread 
ThreadPool.QueueUserWorkItem(objWrkrThread.CallbackMethod, iCount); 

//Worker thread logs an entry in CallbackMethod() 
Global.LogFile.WriteEntry("Hello World"); 

はですこの金庫?クラスの静的インスタンスでメソッドを呼び出すと、誤ってスレッドを「同期」または「ブロック」することはありますか?

マイケル

+0

静的メソッドは、本質的にスレッドセーフではありません。この回答を見るJon Skeet [http://stackoverflow.com/questions/1090650/are-static-methods-thread-safe/1090670#1090670] – TheVillageIdiot

答えて

3

メソッドにコードを記述しない限り、「同期」または「ブロック」するものはありません。インスタンスメソッドでも静的メソッドでもかまいません。

デフォルトでは、WriteEntryはスレッドからの呼び出しをブロックしませんが、複数の同時呼び出しを処理するコードを記述しないと、ファイルが非常に破損する可能性があります。ここでは、このトピックに関する

読む:

Are static methods thread safe

0

それは、それが安全であるように設計されていない限り、複数のスレッドが同時にWriteEntryを呼び出していても安全ではありません。

+0

.NETでシングルトンを行う方法のScottyの例は、複雑すぎる。代わりに、次のような文を書くだけで、明示的なロックを避けることができます: private static Log _instance = new Log(_path) –

0

あなたはシングルトンクラスのための完璧な候補者のような音をやろうとしているもの。私はそれが悪いラップを得ることを知っているが、時にはシンプルさが価値がある。

このようなログクラスを作成すると、スレッドセーフでなければなりません。

public sealed class Log 
{ 
    static Log instance=null; 
    static readonly object lockObject = new object(); 
    static string path = "log.txt"; 

    Log() 
    { 
    } 

    public static Log Instance 
    { 
     get 
     { 
      lock (lockObject) 
      { 
       if (instance==null) 
       { 
        instance = new Log(); 
       } 
       return instance; 
      } 
     } 
    } 

    public void WriteLine(string message) 
    { 
     lock(lockObject) 
     { 
      using(StreamWriter sw = new StreamWriter(File.Open(path, FileMode.Append))) 
      { 
      sw.WriteLine(message); 
      } 
     } 
    } 
} 

次に、あなたのコードでは、あなたはちょうどこのようにそれを呼び出す:

Log executionLog = Log.Instance; 
executionLog.WriteLine("this is a log message."); 

はまた、開口部のオーバーヘッドを取り除くために同様のスレッドセーフな方法でファイルを開いたり閉じたり管理できますすべての書き込みをファイルします。

+0

面白いアイデア、コードscottyを出してくれてありがとう。 –

+0

上記のコードをコンパイルしてもよろしいですか? lockはキーワードであり、オブジェクトの名前として使用することはできません。 – SolutionYogi

+0

@ SolutionYogi、あなたは正しいです。私はそれを打ち込んだだけで、テストはしません。私は自分の答えを更新しました。 – scottm

関連する問題