5

我可以使用FileStream构造函数来确保一次只有一个进程访问文件吗?下面的代码会起作用吗?

public static IDisposable AcquireFileLock() {
    IDisposable lockObj;
    do {
        // spinlock - continually try to open the file until we succeed
        lockObj = TryOpenLockFile();

        // sleep for a little bit to let someone else have a go if we fail
        if (lockObj == null) Thread.Sleep(100); 
    }
    while (lockObj == null);

    return lockObj;
}

private static FileStream TryOpenLockFile() {
    try {
        return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None);
    }
    catch (IOException) {
        return null;
    }
}

特别是,FileMode.Create原子 WRT 的行为是其他进程吗?还有什么我应该使用的吗?

编辑:更具体地说,这是在 Microsoft CLR 上使用单台机器上的本地文件。

4

2 回答 2

2

这将做你想要的。 FileShare.None是重要的部分。

如果所有编写器应用程序都在同一台计算机上,您还可以使用命名的 Mutex来实现相同的目标而无需物理文件,或者如果您不关心谁最后写入文件(仅此而已)来调解文件访问写入不是并发的)。这可以使您不必每次都重新打开文件,并提供阻塞语义而不是Sleep循环(更好的性能)。

请注意,如果名称不被视为机密,即需要保密的信息,任何进程都可以占用您的文件(互斥锁)。

于 2010-11-29T18:05:28.410 回答
1

考虑到以下警告,这将起作用:

  • 您在 Windows 上(通过 Mono 在 Linux 上,由于文件锁是建议性的,因此这不会成立,因此您的方法总是成功)
  • 您正在访问一个本地文件(SMB 也可能会工作,但 NFS 或 WebDAV 几乎肯定不会)
  • 捕获 IOException 可能太宽泛了,您需要专门验证它是否因为共享冲突而失败
于 2010-11-29T18:16:07.880 回答