我可以从Worker线程调用静态类实例上的静态方法吗?

时间:2009-07-08 02:34:56

标签: c# multithreading

我正在使用System.Threading.ThreadPool来管理来自服务的作业队列。我已经实现了这样的日志记录......

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");

这样安全吗?调用类的静态实例上的方法会无意中“同步”或“阻塞”我的线程吗?

迈克尔

3 个答案:

答案 0 :(得分:3)

除非您在方法中编写代码,否则不会“同步”或“阻止”。无论是实例方法还是静态方法都无关紧要。

因此,默认情况下,WriteEntry不会阻止来自您的线程的任何调用,但如果您不编写代码来处理多个同时调用,它可能会很好地破坏文件。

在此处阅读有关此主题的更多信息:

Are static methods thread safe

答案 1 :(得分:0)

让多个线程同时调用WriteEntry是不安全的,除非它被设计为安全的。

答案 2 :(得分: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.");

您还可以使用类似的线程安全方法管理打开文件,以便在每次写入时摆脱打开和关闭文件的过头。