如何在多个进程使用时写入txt文件? C#

时间:2014-03-04 15:06:09

标签: c# .net locking

我有一个尝试写日志文件的记录器。问题似乎是当有多个进程访问同一个日志文件时,记录器无法写入日志文件,导致错误“另一个进程正在使用该文件...”,导致关键信息丢失。我尝试过使用锁,但它似乎不起作用,因为它们是独立的进程(我认为这就是它们不起作用的原因)。有没有办法让多个进程访问文件而不会丢失信息?如果没有,还有其他选择吗?感谢。

3 个答案:

答案 0 :(得分:5)

您的选择没有特别的顺序:

  1. 让不同的进程写入不同的日志文件。如果需要,让这些进程在某个时刻(如午夜)滚动文件,并使用另一个进程来获取昨天的日志并将它们合并在一起。
  2. 如果您拥有/控制您的记录器基础结构并且必须写入同一个日志文件,请查看使用named mutex。命名互斥锁是系统互斥锁,可以跨进程边界共享。 code example at the link显示了如何在进程间共享相同的互斥锁。
    • 正如Florian F在评论中建议的那样,使用log4net可以做到这一点(不止一种方式,包括使用命名的互斥锁)。他们FAQ rightly states如果你这样做就会出现性能问题。
  3. 有一些方法可以对文件进行共享读取和共享写入,然后可以锁定文件的某些区域。您可以尝试多个进程并同步谁写入文件的哪些区域,相应地锁定,等等。但是这样做是非常痛苦的,并且会高度反对它。
  4. 使用syslog服务器。
  5. 使用log4net的远程日志记录功能。

答案 1 :(得分:2)

如Florian所述,Log4Net是一个选项。

另一种选择是使用单独的文件作为锁。如果存在锁定文件,则其他进程执行活动等待,否则它们会创建锁定文件,写入,然后删除锁定文件。

如果您未能创建锁定文件,则意味着在您等待之前,另一个进程已到达此处。

答案 2 :(得分:0)

如果您坚持重新发明轮子并且不使用其他选项(log4net或内存映射文件),则需要延迟写入文件本身,如果与另一个执行相同操作的线程发生冲突,请继续尝试。

使用任务来获取非阻塞函数的超简化版本并以示例的形式显示(不要按原样使用)。

public Task FlushLog(string filePath)
{
  var task = new Task(
  () => 
  while (true)
  {
     try
     {
        var file = new FileStream(filePath, FileMode.OpenOrCreate, 
                                  FileAccess.ReadWrite, FileShare.Read));
        WriteLogToFileInTheUsualWay(file);
        file.Close();
        file.Dispose();
        break;
     }
     catch (UnauthorizedAccessException exception)
     {
        // Sleep randomly and try again
        Thread.Sleep(new Random(DateTime.Now.Milliseconds).Next(1000));
     }
  }
  );
  task.Start();
  return task;
}