简体   繁体   English

多个线程读取同一个文件

[英]Multiple Threads reading from the same file

I have a xml file that needs to be read from many many times.我有一个需要多次读取的 xml 文件。 I am trying to use the Parallel.ForEach to speed this processes up since none of that data being read in is relevant as to what order it is being read in. The data is just being used to populate objects.我正在尝试使用 Parallel.ForEach 来加速这个过程,因为读入的数据都与读入的顺序无关。数据只是用于填充对象。 My problem is even though I am opening the file each time in the thread as read only it complains that it is open by another program.我的问题是,即使我每次在线程中以只读方式打开文件,它也会抱怨它被另一个程序打开。 (I don't have it opened in a text editor or anything :)) (我没有在文本编辑器或任何东西中打开它:))

How can I accomplish multi reads from the same file?如何从同一个文件中完成多次读取?

EDIT: The file is ~18KB pretty small.编辑:该文件约为 18KB,非常小。 It is read from about 1,800 times.它被读取了大约 1,800 次。

Thanks谢谢

If you want multiple threads to read from the same file, you need to specify FileShare.Read :如果希望多个线程从同一个文件中读取,则需要指定FileShare.Read

using (var stream = File.Open("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    ...
}

However, you will not achieve any speedup from this, for multiple reasons:但是,由于多种原因,您不会因此而获得任何加速:

  1. Your hard disk can only read one thing at a time.您的硬盘一次只能读取一件事。 Although you have multiple threads running at the same time, these threads will all end up waiting for each other.尽管您有多个线程同时运行,但这些线程最终都会相互等待。
  2. You cannot easily parse a part of an XML file.您无法轻松解析 XML 文件的一部分。 You will usually have to parse the entire XML file every time.您通常每次都必须解析整个 XML 文件。 Since you have multiple threads reading it all the time, it seems that you are not expecting the file to change.由于您有多个线程一直在读取它,因此您似乎不希望文件发生更改。 If that is the case, then why do you need to read it multiple times?既然如此,那为什么还要读多遍呢?

Depending on the size of the file and the type of reads you are doing it might be faster to load the file into memory first, and then provide access to it directly to your threads.根据文件的大小和您正在执行的读取类型,首先将文件加载到内存中可能会更快,然后直接向您的线程提供对它的访问。

You didnt provide any specifics on the file, the reads, etc so I cant say for sure if it would address your specific needs.您没有提供有关文件、读取等的任何细节,因此我无法确定它是否能满足您的特定需求。

The general premise would be to load the file once in a single thread, and then either directly (via the Xml structure) or indirectly (via XmlNodes, etc) provide access to the file to each of your threads.一般前提是在单个线程中加载一次文件,然后直接(通过 Xml 结构)或间接(通过 XmlNodes 等)为每个线程提供对文件的访问。 I envision something similar to:我设想类似于:

  1. Load the file加载文件
  2. For each Xpath query dispatch the matching nodes to your threads.对于每个 Xpath 查询,将匹配的节点分派到您的线程。

If the threads dont modify the XML directly, this might be a viable alternative.如果线程不直接修改 XML,这可能是一个可行的替代方案。

When you open the file, you need to specify FileShare.Read :打开文件时,需要指定FileShare.Read

using (var stream = new FileStream("theFile.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    ...
}

That way the file can be opened multiple times for reading这样可以多次打开文件进行阅读

While an old post, it seems to be a popular one so I thought I would add a solution that I have used to good effect for multi-threaded environments that need read access to a file.虽然是旧帖子,但它似乎很受欢迎,所以我想我会添加一个解决方案,我曾经使用过该解决方案对需要对文件进行读取访问的多线程环境有很好的效果。 The file must however be small enough to hold in memory at least for the duration of your processing, and the file must only be read and not written to during the period of shared access.但是,该文件必须足够小以至少在处理期间保存在内存中,并且该文件只能在共享访问期间读取而不能写入。

string FileName = "TextFile.txt";
string[] FileContents = File.ReadAllLines(FileName);

foreach (string strOneLine in FileContents)
{
  // Do work on each line of the file here
}

So long as the file is only being read, multiple threads or programs can access and process it at the same time without treading on one another's toes.只要文件只是被读取,多个线程或程序就可以同时访问和处理它,而不会相互影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM