设计问题:C# 应用程序中多个线程需要访问日志文件以进行读/写
我在尝试读取和/或写入日志文件的 ac# 应用程序中遇到多个线程问题。偶尔会抛出异常,我怀疑这是由于冲突造成的。有没有一种好方法可以保证每个线程打开文件时的独占访问权限?
I am having issues with multiple threads in a c# application trying to read and/or write to a log file. Occasionally an exception is thrown, and I am suspecting this is due to collisions. Is there a good way to guarantee exclusive access for each thread when it opens the files?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以通过锁定记录器类中的同步对象来解决这个问题。像这样的东西是可行的,这就是我为我的记录器代码所做的。
这会同步文件写入并保证不会发生写入“冲突”。
You can fix that with locking a sync object in the logger class. Something like this would work and is what I do for my logger code.
This synchronizes the file writes and guarantees that you won't have write "collisions".
锁定可能是这里更合适的方式。如果性能至关重要,您可以采用某种日志消息排队方式,例如 ConcurrentQueue,它应该针对并发读/写以及生产者消费者模式进行相当优化。
Locking is probably the more suitable way here. If performance is critical, you could resort to some kind of queuing of the log messages with e.g. a
ConcurrentQueue<T>
, which should be quite optimized for concurrent read/write, together with a producer consumer pattern.最简单的方法是使用开箱即用的线程安全日志框架,例如 log4net。
如果由于某种原因您无法使用日志记录框架,则必须使用上面提到的线程同步方法之一并自行管理访问。
The simplest thing to do is use a logging framework, such as log4net, that is thread-safe out of the box.
If for some reason you cannot use a logging framework, you will have to use one of the thread-syncing methods mentioned above and manage access yourself.
文件系统通常具有内置锁定系统,因此除非您的线程都使用相同的 Stream 对象,否则应该没问题。如果不是,请为每个文件访问设置您自己的锁(通常可以进行并发读取,但如果您不想为每个文件使用不同的流,则这是不可能的):
我但是,建议您为每个访问或每个线程创建不同的流。如果您使用不同的流,我认为这不是您的问题...
请注意,这不算是创建新流:
因为它仍然使用相同的基础
Stream< /代码> 对象。
Filesystems generally have built-in locking systems, so unless your threads are all using the same
Stream
object then you should be fine. If they're not, set up your own lock for each file access (normally concurrent reads can be done but if you don't want to use a different stream for each one it is impossible):I would recommend you create a different stream for each access or each thread, however. If you are using different streams, I don't think that's your problem...
Note that this doesn't count as creating a new stream:
because it still uses the same base
Stream
object.只用于日志记录并通过并发队列和精简等待事件进行通信的线程怎么样?
然后,您可以以非阻塞方式从多个线程写入,这对于多处理器系统很有好处。
您只需将一个新的日志对象或更好的、一个结构体或一个字符串放入队列,然后接收队列事件的线程就可以以完全异步的方式打印\写入\保存\操作接收到的消息。
您也可以从该队列中读取文件,并将消息发送到该线程(例如调用或发送消息)。
What about a thread only for logging that communicates through a concurrent queue and slim wait events?
Then you can write from multiple threads in a non-blocking way, good for multiprocessor systems.
You just enqueue a new log object or better, a struct or just a string and the thread that receive queue events can then print\write\save\manipulate the received messages in a totally asynchronous way.
You can read files from that queue with messages to that thread too (something like invokes or sendmessage).
您可以使用对象来锁定文件。
将文件访问代码写入
lock(object) { your file access code ... }
中,这样就不会同时执行。You can use an object to lock the file.
Write your file access code within
lock(object) { your file access code ... }
so that it will not be executed simultaneously.