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

时间:2014-09-11 20:50:14

标签: c# multithreading

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

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

我对C#和一般的多线程有些新意,所以如果有人能指出我在这里正确的方向,我将非常感激。

3 个答案:

答案 0 :(得分:3)

错误消息表明该文件由另一个进程保持打开,而不是线程。您确定每次运行应用程序时文件都已正确关闭吗?

一般来说,您应该使用锁来控制对应用程序内共享资源的访问。例如,如果您有一个带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()确保在进程终止时文件未保持打开状态; - )

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

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

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

作为替代解决方案

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