2011-02-18 89 views
4

我有一个文本文件,多个线程/进程将写入它(它是一个日志文件)。在文件系统级同步写入文件

由于并发写入,文件有时会损坏。

我想使用文件系统级自身的所有线程的文件写入模式。

我知道可以使用锁(多进程互斥锁)并同步写入此文件,但我更愿意以正确的模式打开文件并将任务保留到System.IO

可能吗?这种情况下的最佳做法是什么?

+0

所有的进程是在同一台机器上运行,还是在访问网络共享上的文件? – 2011-02-18 18:46:33

+0

我不认为(但我不是100%肯定)有一种方法可以在“等待它可以锁定”类型的共享模式下打开文件。我认为唯一能做到你想做的就是使用互斥体。当然,如果你在网络共享上打开一个文件,那也不是解决方案,你可能需要设置一个服务器来接受日志调用。 – 2011-02-18 18:47:31

+0

@Lasse:同一台机器上的所有线程/进程(windows) – Xaqron 2011-02-18 18:58:51

回答

1

您可以使用File.Open(),将FileShare的值设置为None,并使每个线程等待(如果它无法访问该文件)。

+0

我认为这将导致访问异常,除非有阻塞调用或等待句柄。 – Xaqron 2011-02-18 18:44:16

3

最好的办法就是使用锁/ mutexex。这是一个简单的方法,它的工作原理,你可以很容易地理解它并推理它。

当涉及到同步时,它通常会从最简单的解决方案开始,并且只有在遇到问题时才会尝试优化。

2

据我所知,Windows没有你要找的东西。没有文件句柄对象通过在写入文件时阻止所有其他用户来进行自动同步。

如果你的日志涉及三个步骤,打开文件,写,关闭文件,然后你可以有你的线程试图在独占模式(FileShare.None)打开该文件,如果无法打开,捕获异常,然后再试一次直到成功。我发现最好的是乏味。

在我从多个线程登录的程序中,我创建了一个基本上是队列的后代。线程调用该对象上的WriteWriteLine方法,该方法将输出格式化并放入队列中(使用BlockingCollection)。单独的日志记录线程为该队列提供服务 - 从中​​抽取事件并将它们写入日志文件。这有几个好处:

  • 线程不必为了登录
  • 只有一个线程在相互等待被写入文件
  • 是微不足道的旋转日志(即启动一个新的记录每一个小时文件等)
  • 有一个错误的几率为零,因为我忘了做一些螺纹

这样做跨进程将是一个更加困难的锁定。我从来没有考虑过跨进程共享日志文件。如果我需要,我会创建一个单独的应用程序(一个日志服务)。该应用程序将执行实际写入操作,其他应用程序传递字符串以进行写入。同样,这可以确保我不能搞砸,而且我的代码仍然很简单(即客户端没有显式锁定代码)。