I am using a System.Threading.ThreadPool to manage a queue of jobs from a service. I have already implemented logging like this...
我正在使用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);
}
}
}
I want to create the log at service startup and use it from my queued worker threads.. something like this...
我想在服务启动时创建日志并从我的排队工作线程中使用它..这样的事情......
//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");
Is this safe? Will calling a method on a static instance of a class inadvertently 'synchronise' or 'block' my threads?
这样安全吗?是否会在类的静态实例上调用方法无意中“同步”或“阻塞”我的线程?
Michael
3 个解决方案
#1
Nothing will 'synchronize' or 'block' unless you write code in your method. It doesn't matter whether it's an instance method or static method.
除非您在方法中编写代码,否则什么都不会“同步”或“阻止”。无论是实例方法还是静态方法都无关紧要。
So by default, WriteEntry won't block any calls from your threads but it could very well corrupt file if you don't write the code to handle multiple simultaneous calls.
因此,默认情况下,WriteEntry不会阻止来自您的线程的任何调用,但如果您不编写代码来处理多个同时调用,它可能会很好地破坏文件。
Read more on this topic here:
在这里阅读更多关于这个主题:
Are static methods thread safe
静态方法是否安全
#2
It's not safe to have multiple threads call WriteEntry at the same time unless it was designed to be safe.
除非设计为安全,否则让多个线程同时调用WriteEntry是不安全的。
#3
What you are trying to do sounds like the perfect candidate for a Singleton class. I know it gets a bad wrap, but sometimes it's simplicity is worth it.
你想要做的事听起来像是Singleton课程的完美候选人。我知道它会变坏,但有时它的简单性是值得的。
You can create a log class like this and you should be thread safe.
您可以创建这样的日志类,并且您应该是线程安全的。
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);
}
}
}
}
Then in your code, you just call it like this:
然后在您的代码中,您只需将其称为:
Log executionLog = Log.Instance;
executionLog.WriteLine("this is a log message.");
You could also manage opening the file in similar thread safe methods to get rid of the over head of opening and closing the file every write.
您还可以使用类似的线程安全方法管理打开文件,以消除每次写入时打开和关闭文件的问题。
#1
Nothing will 'synchronize' or 'block' unless you write code in your method. It doesn't matter whether it's an instance method or static method.
除非您在方法中编写代码,否则什么都不会“同步”或“阻止”。无论是实例方法还是静态方法都无关紧要。
So by default, WriteEntry won't block any calls from your threads but it could very well corrupt file if you don't write the code to handle multiple simultaneous calls.
因此,默认情况下,WriteEntry不会阻止来自您的线程的任何调用,但如果您不编写代码来处理多个同时调用,它可能会很好地破坏文件。
Read more on this topic here:
在这里阅读更多关于这个主题:
Are static methods thread safe
静态方法是否安全
#2
It's not safe to have multiple threads call WriteEntry at the same time unless it was designed to be safe.
除非设计为安全,否则让多个线程同时调用WriteEntry是不安全的。
#3
What you are trying to do sounds like the perfect candidate for a Singleton class. I know it gets a bad wrap, but sometimes it's simplicity is worth it.
你想要做的事听起来像是Singleton课程的完美候选人。我知道它会变坏,但有时它的简单性是值得的。
You can create a log class like this and you should be thread safe.
您可以创建这样的日志类,并且您应该是线程安全的。
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);
}
}
}
}
Then in your code, you just call it like this:
然后在您的代码中,您只需将其称为:
Log executionLog = Log.Instance;
executionLog.WriteLine("this is a log message.");
You could also manage opening the file in similar thread safe methods to get rid of the over head of opening and closing the file every write.
您还可以使用类似的线程安全方法管理打开文件,以消除每次写入时打开和关闭文件的问题。