0

背景:我有几个不同的线程,每个线程都需要写入日志文件(.txt)。我需要一种在线程之间共享此文件的方法,但我不知道如何去做,我已经读到可能使用某种队列,并轮询此队列以将消息推送到文本文件等. 或者我是否需要锁定文件并在前面的一个完成后将消息放入队列中写入?

目前我正在这样写;

  fileToWrite = new System.IO.StreamWriter(DeviceManager.logPath + correctDateTimeFormat);

但是我收到了错误消息;

 The process cannot access the file 'filename' because it is being used by another process.

我只能假设多个线程正在尝试同时访问它。

谁能指出我应该采取什么方法的正确方向?

4

2 回答 2

2

这是您在这里面临的两个不同的问题。

  1. 在文件关闭之前再次打开文件 - 这可以通过使用适当的共享标志打开来完成
  2. 同步访问它。这可以通过使用一些互斥锁来一次只允许 1 个线程访问文件来完成。这很重要,因为否则,您可能会让线程同时写入文件,这可能会导致问题,例如消息在 self.

这个带参数的FileStream 构造FileSharing函数可以帮助您在关闭文件之前从几个线程打开文件。

但是,根据您的需要,最好将文件(例如,日志文件)的访问集中在一个地方(创建一个类,该类具有一个控制对该特定文件的访问的实例)并确保,它将通过锁定一些私有互斥锁来同步来自不同线程的访问,因此您不会同时从几个线程写入文件。

非常简单的示例,需要构建:

class Logger : IDisposable
{
    private FileStream file; //Only this instance have a right to own it
    private StreamWriter writer;
    private object mutex; //Mutex for synchronizing

    public Logger(string logPath)
    {
        file = new FileStream(logPath);
        writer = new StreamWriter(file);
        mutex = new object();
    }

    // Log is thread safe, it can be called from many threads
    public void Log(string message)
    {
        lock (mutex)
        {
             writer.WriteLine(message);
        }
    }

    public void Dispose()
    {
          writer.Dispose(); //Will close underlying stream
    }
}

再一次,它非常简单,只是为了展示我们在这里试图实现的基本规则。

您在这里几乎没有其他选择:

  1. 使用现成的日志库(Log4Net 或 NLog(我个人更喜欢))
  2. 日志可以将消息添加到队列中,您可以有另一个线程,内部用于记录器从该队列读取消息并写入它们,这样,记录器的调用者将不必等待日志消息完成记录
于 2012-06-29T13:13:55.503 回答
1

查看这篇文章,了解如何在 wpf http://codetechnics.blogspot.com/2010/09/how-to-configure-initialize-and-using.html中使用 log4net 如果您收到错误 The type or namespace name 'log4net ' 找不到(您是否缺少 using 指令或程序集引用?)

因为 log4net显然需要访问system.web.dll,它不包含在客户端配置文件中

打开项目的属性页面,将Target Framework设置为.Net Framework 4并保存更改。

于 2012-06-29T13:37:13.827 回答