【问题标题】:How to write to a txt file when multiple processes are using it? C#多个进程使用时如何写入txt文件? C#
【发布时间】:2014-03-04 15:06:09
【问题描述】:

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

【问题讨论】:

  • 是的,log4net
  • @FlorianF。 log4net FAQ 确实说它可以做到,但警告不要这样做。我会更新我的答案以反映它。
  • 为什么多个进程使用同一个记录器?您可以创建一个管理流程,他将拥有单例记录器 WCF 服务。

标签: c# .net locking


【解决方案1】:

您的选择不分先后:

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

【讨论】:

    【解决方案2】:

    Log4Net 是一个选项,正如 Florian 所提到的。

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

    如果您未能创建锁定文件,则意味着另一个进程在您之前到达那里并且您一直在等待。

    【讨论】:

    • 如果 OP 不想使用任何第 3 方代码,这似乎是最佳选择。但是,您可以添加一个示例。尽管如此,还是投了赞成票。
    • 如果登录到 UNC 路径并且进程可能在不同的盒子上,这是一个不错的选择。如果在同一个盒子上,命名互斥体会更有效。
    【解决方案3】:

    如果您坚持重新发明轮子而不使用其他选项(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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-27
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多