为什么此代码中的锁不起作用?

San*_*ira 5 c# locking

使用此代码用于非常基本的记录器:

lock (string.Concat("LogWritter_", this.FileName))
{
    using (var fileStream = File.Open(this.FileName, FileMode.Append, FileAccess.Write, FileShare.Read))
    {
        using (var w = new StreamWriter(fileStream))
        {
            w.Write(message);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我从几个线程同时尝试它时,我很快得到错误:

The process can't access the file because its being used by another file.
Run Code Online (Sandbox Code Playgroud)

为什么锁不会阻止线程同时访问文件?

如果线程将同一实例或不同实例调用到同一文件,则无关紧要.另外我认为这可能是因为在Windows中编写文件时会有一些延迟,但在Linux上也会发生同样的事情.

emp*_*mpi 12

您正在锁定临时字符串.你必须引入一个静态对象来锁定.

  • 不管字符串多少次,字符串不应该只是一次不可变/存储吗? (2认同)

spe*_*der 8

Dictionary<string,object>使用文件路径作为密钥创建并存储锁定对象.

前一阵子,我接近同样的问题:

按字符串锁定.这样安全/理智吗?

  • 虽然这个答案错过了一些上下文,但如果你不想为多个文件单一锁定,这是正确的方法.查看一些[logging framework](http://logging.codeplex.com)的[this implementation](http://logging.codeplex.com/SourceControl/changeset/view/72677#1298869).该实现使用`OrdinalIgnoreCase``Fontword`并确保使用规范文件路径(重要). (2认同)

The*_*Saw 5

在C#lock语句放在锁的对象,而不是字符串的独特性上.因此,因为您是动态连接两个字符串,所以基本上每次创建一个新对象,因此每个锁都是唯一的.即使您每次都访问同一个文件,"A"+"B"也会产生一些新的不可变字符串; "A"+"B"再次导致另一个新对象.