C# 多进程读写一个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18690537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:56:18  来源:igfitidea点击:

Multi processes read&write one file

c#multithreading

提问by Lcng

I have a txt file ABC.txt which will be read and wrote by multi processes. So when one process is reading from or writing to file ABC.txt, file ABC.txt must be locked so that any other processes can not reading from or writing to it. I know the enum System.IO.FileShare may be the right way to handle this problem. But I used another way which I'm not sure if it is right. The following is my solution.

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

I added another file Lock.txt to the folder. Before I can read from or write to file ABC.txt, I must have the capability to read from file Lock.txt. And after I have read from or written to file ABC.txt, I have to release that capability. The following is the code.

我在文件夹中添加了另一个文件 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

On my computer, it seems that this solution works well, but I still can not make sure if it is appropriate..

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

Edit:Multi processes, not multi threads in the same process.

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

采纳答案by bytefire

C#'s named EventWaitHandleis the way to go here. Create an instance of wait handle in every process which wants to use that file and give it a name which is shared by all such processes.

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

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

Then when accessing the file wait on waitHandleand when finished processing file, set it so the next process in the queue may access it.

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

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

When you name an event wait handle then that name is shared across all processes in the operating system. Therefore in order to avoid possibility of collisions, use a guid for name ("SHARED_BY_ALL_PROCESSES" above).

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

回答by bluetoft

C# has a built in lockand you can use it by creating a static object which all threads have acess to:

C# 有一个内置的lock,你可以通过创建一个所有线程都可以访问的静态对象来使用它:

private static object lockObject {get;set;}

public static object LockObject {get{return lockObject ?? lockObject = new object();}}


void YourMethod()
{
   lock(LockObject)  // all other threads will wait for y
   {
      using(var lockFileStream = File.Open("Lock.txt", FileMode.Open, FileAccess.Read, FileShare.None))
      {
         //Do what you need with the file.  
      }

   }
}

This creates a Thread Safe approach to your problem.

这为您的问题创建了线程安全的方法。

回答by Omaha

Your solution is error prone. You've basically implemented double-checked locking (http://en.wikipedia.org/wiki/Double-checked_locking) which can be very unsafe.

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

A better solution would be to either introduce thread isolation, whereby only one thread ever accesses the file and does so by reading from a queue upon which requests to read or write are placed by other threads (and of course the queue is protected by mutually exclusive access by threads) or where the threads synchronize themselves either by synchronization devices (locksections, mutices, whatever) or by using some other file access logic (for example, System.IO.FileSharecame up in a few reponses here.)

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

回答by Jeremy Bell

If it was me, I would install something like SQL Server Compact Edition for reading/writing this data.

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

However, if you want to be able to lock access to a resource that is shared between multiple processes, you need to use a Mutex or a Semaphore.

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

The Mutex class is a .Net wrapper around an OS Level locking mechanism.

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

Overview of Synchronization Primitives

同步原语概述

回答by Jake Drew

A mutex in C# may be shared across multiple processes. Here is an example for multiple processes writing to a single file:

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

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

You need to make sure that the mutex is given a unique name that will be shared across the entire system.

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

Additional reading here:

补充阅读在这里:

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

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