多线程C#应用程序日志文件锁定问题

本文关键字:文件锁 锁定 问题 文件 日志 应用程序 多线程 | 更新日期: 2023-09-27 18:21:44

我有一个双线程c#应用程序,其中两个线程都写入同一日志,但我收到了一个错误。

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

一般来说,我对C#和多线程有点陌生,所以如果有人能在这里为我指明正确的方向,我将不胜感激。

多线程C#应用程序日志文件锁定问题

错误消息表示文件由另一个进程而非线程打开。你确定每次运行应用程序时都正确关闭了文件吗?

一般来说,您应该使用锁来控制对应用程序中共享资源的访问。例如,如果您有一个带有Log()函数的LogWriter类,那么一个没有排队的最小实现可能如下所示:

public class LogWriter
{
private readonly object _lock = new object;
public void Log(string message)
{
    lock(_lock)
    {
        //write message to log file
        string appName = Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0]);
        StreamWriter sw = new StreamWriter(Environment.CurrentDirectory + Path.DirectorySeparatorChar + appName + ".log", true);
        sw.WriteLine(string.Format("{0:u} {1}", DateTime.Now, message));
        sw.Flush();
        sw.Close();
    }
}

lock(_lock)确保一次只有一个线程访问该文件。sw.Close()确保在进程终止时不会打开文件;-)

正如错误消息所述,您不能从多个不同的线程创建编写器。您需要找到某种方法来同步线程之间对文件的访问,也就是说,确保一个线程等待尝试访问该文件,直到所有其他线程都完成为止,或者您可以将单个线程指定为负责访问该文件的线程,要求所有其他想要访问该文件的线程请求其他线程为其进行访问。

您需要创建一个可供并行线程访问的列表(或任何您喜欢的数据结构)。然后在每个线程中将记录添加到该列表中

 lock (yourList) {
    // here you can add items to the List
  }

完成后,将您的列表转储到一个文件中。或者为每个线程创建一个新的列表,将它们全部返回,然后将所有列表合并为一个列表。或者使用数据库并将记录添加到表中(最符合逻辑的解决方案)

作为替代解决方案

  1. 创建全局列表
  2. 将该列表传递给所有线程并锁定它(上面的示例)并写入它;解锁它
  3. 创建另一个具有延迟的无限循环线程
  4. 在无限循环中,延迟后,锁定列表,获取所有数据,写入文件,清空列表
  5. 发布列表