2009-07-08 120 views
0

我正在使用System.Threading.ThreadPool來管理來自服務的作業隊列。我已經執行記錄這樣的...我可以從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 2009-07-08 02:40:12

回答

3

除非您在方法中編寫代碼,否則將不會「同步」或「阻止」。無論它是實例方法還是靜態方法都無關緊要。

因此,默認情況下,WriteEntry不會阻止來自線程的任何調用,但如果不編寫代碼來處理多個同時調用,它可能會損壞文件。

瞭解更多關於這個話題在這裏:

Are static methods thread safe

0

這不是安全有多個線程在同一時間打電話WriteEntry,除非它被設計是安全的。

+0

事實證明,Scotty在.NET下如何做singleton的例子是太複雜。相反,你可以通過寫下類似的東西來避免顯式鎖定: private static Log _instance = new Log(_path) – 2009-07-08 03:18:47

0

你正在嘗試做聽起來像是一個Singleton類的最佳人選。我知道它有一個不好的包裝,但有時它簡單是值得的。

你可以像這樣創建一個日誌類,你應該是線程安全的。

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。 – 2009-07-08 03:18:31

相關問題