设计问题:多个线程需要访问日志文件以便在c#应用程序中进行读/写

时间:2011-08-31 18:36:29

标签: c# logging thread-safety

我在尝试读取和/或写入日志文件的c#应用程序中遇到多个线程的问题。偶尔会抛出一个异常,我怀疑这是由于碰撞造成的。有没有一种方法可以保证每个线程在打开文件时都能独占访问?

6 个答案:

答案 0 :(得分:1)

您可以通过在记录器类中锁定同步对象来解决此问题。像这样的东西会起作用,这就是我为记录器代码所做的事情。

private static readonly object syncObject = new object();

// .. when ready to write to a file in a method
lock(syncObject)
{
    // write to file here, 
    // no other thread is able to write to the file while this is locked
}

这会同步文件写入并保证您不会写“冲突”。

答案 1 :(得分:1)

锁定可能是更合适的方式。如果性能至关重要,您可以使用某种方式对日志消息进行排队。一个ConcurrentQueue<T>,它应该针对并发读/写以及生产者消费者模式进行了相当优化。

答案 2 :(得分:1)

最简单的方法是使用日志框架,例如log4net,它是开箱即用的线程安全的。

如果由于某种原因您无法使用日志记录框架,则必须使用上面提到的其中一种线程同步方法并自行管理访问权限。

答案 3 :(得分:0)

您可以使用对象锁定文件。

lock(object) { your file access code ... }内写下您的文件访问代码,以便不会同时执行。

答案 4 :(得分:0)

文件系统通常具有内置锁定系统,因此除非您的线程都使用相同的Stream对象,否则您应该没问题。如果他们,请为每个文件访问设置自己的锁(通常可以进行并发读取,但如果您不想为每个文件使用不同的流,则不可能):< / p>

lock(streamObject) {
    // access the file here
}

我建议您为每个访问或每个线程创建不同的流。如果 使用不同的流,我认为这不是你的问题......

请注意,这并不算作创建新流:

using(StreamReader sr = new StreamReader(theBaseStream)) {
 ...

因为它仍然使用相同的基础Stream对象。

答案 5 :(得分:0)

仅用于通过并发队列和苗条等待事件进行通信的日志记录的线程怎么样?

然后,您可以以非阻塞方式从多个线程写入,适用于多处理器系统。

您只需将一个新的日志对象或更好的,一个结构或一个字符串排入队列,然后接收队列事件的线程就可以以完全异步的方式打印\ write \ save \操纵收到的消息。

您可以从该队列中读取包含该线程消息的文件(类似于invokes或sendmessage)。