2009-07-08 123 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

相关问题