37

我有一个 txt 文件 ABC.txt,它将被多个进程读取和写入。因此,当一个进程正在读取或写入文件 ABC.txt 时,文件 ABC.txt 必须被锁定,以使任何其他进程无法读取或写入它。我知道枚举 System.IO.FileShare 可能是处理这个问题的正确方法。但是我使用了另一种方法,我不确定它是否正确。以下是我的解决方案。

我在文件夹中添加了另一个文件 Lock.txt。在我可以读取或写入文件 ABC.txt 之前,我必须具有读取文件 Lock.txt 的能力。在我读取或写入文件 ABC.txt 之后,我必须释放该功能。以下是代码。

        #region Enter the lock
        FileStream lockFileStream = null;
        bool lockEntered = false;
        while (lockEntered == false)
        {
            try
            {
                lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None);
                lockEntered = true;
            }
            catch (Exception)
            {
                Thread.Sleep(500);
            }
        }
        #endregion

        #region Do the work
        // Read from or write to File ABC.txt
        // Read from or write to other files
        #endregion

        #region Release the lock
        try
        {
            if (lockFileStream != null)
            {
                lockFileStream.Dispose();
            }
        }
        catch
        {
        }
        #endregion

在我的电脑上,这个解决方案似乎运作良好,但我仍然无法确定它是否合适..

编辑:多进程,而不是同一进程中的多线程。

4

4 回答 4

54

C# 的命名EventWaitHandle是这里的方法。在每个想要使用该文件的进程中创建一个等待句柄的实例,并为其指定一个由所有此类进程共享的名称。

EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, "SHARED_BY_ALL_PROCESSES");

然后在访问文件时等待waitHandle和完成处理文件时,设置它以便队列中的下一个进程可以访问它。

waitHandle.WaitOne();
/* process file*/
waitHandle.Set();

当您命名事件等待句柄时,该名称将在操作系统中的所有进程之间共享。因此,为了避免发生冲突的可能性,请使用 guid 作为名称(上面的“SHARED_BY_ALL_PROCESSES”)。

于 2013-09-09T06:56:57.357 回答
16

C# 中的互斥锁可以在多个进程之间共享。这是多个进程写入单个文件的示例:

using (var mutex = new Mutex(false, "Strand www.jakemdrew.com"))
{
    mutex.WaitOne();
    File.AppendAllText(outputFilePath,theFileText);
    mutex.ReleaseMutex();
}

您需要确保为互斥锁指定一个唯一的名称,该名称将在整个系统中共享。

此处补充阅读:

http://www.albahari.com/threading/part2.aspx#_Mutex

于 2016-06-29T05:42:36.380 回答
4

您的解决方案容易出错。您基本上已经实现了双重检查锁定(http://en.wikipedia.org/wiki/Double-checked_locking),这可能非常不安全。

更好的解决方案是引入线程隔离,即只有一个线程访问文件,并通过从队列中读取来访问文件,在该队列上读取或写入请求由其他线程放置(当然队列受互斥保护通过线程访问)或线程通过同步设备(lock部分、mutice 等)或通过使用其他文件访问逻辑(例如,System.IO.FileShare在此处出现的一些响应)进行自身同步。

于 2013-09-09T02:15:06.127 回答
0

如果是我,我会安装类似 SQL Server Compact Edition 的东西来读取/写入这些数据。

但是,如果您希望能够锁定对在多个进程之间共享的资源的访问,则需要使用 Mutex 或 Semaphore。

Mutex 类是围绕操作系统级别锁定机制的 .Net 包装器。

同步原语概述

于 2013-09-09T04:13:04.327 回答