C# 在C中从多个线程读取同一文件

C# 在C中从多个线程读取同一文件,c#,.net,multithreading,C#,.net,Multithreading,我在谷歌上搜索了一些关于这方面的建议,并找到了一些链接。最明显的是,但最后我想知道的是我的代码实现得有多好 我基本上有两门课。一个是转换器,另一个是转换器线程 我创建了这个转换器类的一个实例,它有一个属性ThreadNumber,告诉我应该同时运行多少个线程,这是从用户那里读取的,因为这个应用程序将在多cpu系统上实际使用,比如8个cpu,所以支持它,这将加速导入 转换器实例读取的文件范围从100mb到800mb,该文件的每一行都是一个选项卡分隔值记录,该记录被导入到另一个目标(如数据库)中 C

我在谷歌上搜索了一些关于这方面的建议,并找到了一些链接。最明显的是,但最后我想知道的是我的代码实现得有多好

我基本上有两门课。一个是转换器,另一个是转换器线程

我创建了这个转换器类的一个实例,它有一个属性ThreadNumber,告诉我应该同时运行多少个线程,这是从用户那里读取的,因为这个应用程序将在多cpu系统上实际使用,比如8个cpu,所以支持它,这将加速导入

转换器实例读取的文件范围从100mb到800mb,该文件的每一行都是一个选项卡分隔值记录,该记录被导入到另一个目标(如数据库)中

ConverterThread类只是在线程new ThreadConverterThread.StartThread中运行,并具有事件通知功能,因此当其工作完成时,它可以通知Converter类,然后我可以总结所有这些线程的进度,并在GUI中通知用户,例如,有多少记录已导入,有多少记录字节已被读取

看来,,然而,我遇到了一些麻烦,因为我得到了关于文件无法读取的随机错误,或者进度百分比的总和超过了100%,这是不可能的,我认为这是因为线程没有得到很好的管理,并且事件返回的信息可能是错误的,因为它从一个线程传输穿行

你有没有关于更好的线程实现实践的建议,这样我就可以完成这个任务


提前感谢。

我在自己的一些代码中读取了非常大的文件,我必须告诉您,我对向读取操作添加线程实际上会提高整体读取性能的说法持怀疑态度。事实上,添加线程可能会导致头部搜索,从而降低性能。这种类型的任何文件操作都很可能是I/O绑定的,而不是CPU绑定的

考虑到您引用的文章的作者从未实际提供过“真实”代码,他声称多线程将加速I/O,但其他线程仍无法实现。任何通过添加线程来提高硬盘读/写性能的尝试都肯定会受到I/O的限制,除非他在读取之间进行了认真的数字运算,或者偶然发现了一些与磁盘缓存有关的巧合,在这种情况下,性能改进可能无法在具有不同硬件特性的另一台机器上实现

通常,当涉及到这种大小的文件时,即使可以利用线程,性能的额外20%或30%的提高也不会有多大影响,因为这样的任务肯定会被认为是后台任务,而不是实时任务。我在这类工作中使用多线程,不是因为它提高了一个文件的读取性能,而是因为可以在后台同时处理多个文件


在使用线程执行此操作之前,我仔细地对软件进行了基准测试,以查看线程是否确实能够提高总体吞吐量。在我的开发机器上的测试结果是,使用与处理器内核数量相同的线程数量可以产生最大可能的吞吐量。但是,这是每个线程处理一个文件。

我在自己的一些代码中读取了非常大的文件,我必须告诉您,我对向读取操作添加线程实际上会提高整体读取性能的说法表示怀疑。事实上,添加线程可能会导致头部搜索,从而降低性能。这种类型的任何文件操作都很可能是I/O绑定的,而不是CPU绑定的

考虑到您引用的文章的作者从未实际提供过“真实”代码,他声称多线程将加速I/O,但其他线程仍无法实现。任何通过添加线程来提高硬盘读/写性能的尝试都肯定会受到I/O的限制,除非他在读取之间进行了认真的数字运算,或者偶然发现了一些与磁盘缓存有关的巧合,在这种情况下,性能改进可能无法在具有不同硬件特性的另一台机器上实现

通常,当涉及到这种大小的文件时,即使可以利用线程,性能的额外20%或30%的提高也不会有多大影响,因为这样的任务肯定会被认为是后台任务,而不是实时任务。我在这类工作中使用多线程,不是因为它提高了一个文件的读取性能,而是因为可以在后台同时处理多个文件

在使用线程执行此操作之前,我仔细地对软件进行了基准测试,以查看线程是否确实能够提高总体吞吐量。在我的开发机器上的测试结果是使用
线程的数量与处理器内核的数量相同,可以产生最大的吞吐量。但这是每个线程处理一个文件。

多个线程一次读取一个文件会带来麻烦。我将建立一个生产者-消费者模型,这样生产者可以读取文件中的行,可能是读到一个缓冲区中,然后在消费者线程完成处理当前工作负载时将它们交给消费者线程。这确实意味着你有一个阻塞点,在那里,行被分发出去,但是如果处理过程比读取过程需要更长的时间,那么这应该不是什么大问题。如果阅读是慢的部分,那么你真的不需要多个消费者

多线程一次读取一个文件会带来麻烦。我将建立一个生产者-消费者模型,这样生产者可以读取文件中的行,可能是读到一个缓冲区中,然后在消费者线程完成处理当前工作负载时将它们交给消费者线程。这确实意味着你有一个阻塞点,在那里,行被分发出去,但是如果处理过程比读取过程需要更长的时间,那么这应该不是什么大问题。如果阅读是慢的部分,那么你真的不需要多个消费者

您应该尝试只让一个线程读取文件,因为无论如何,多个线程都可能被I/O绑定。然后,您可以将这些行馈送到一个线程安全队列中,多个线程可以从该队列中取出要解析的行


您将无法告诉任何一个线程的进度,因为该线程没有定义的工作量。但是,您应该能够通过跟踪总共有多少项已添加到队列中以及有多少项已取出来跟踪大致进度。显然,当您的文件读取器线程将更多行放入队列时,您的进度似乎会下降,因为有更多行可用,但您应该能够比工作人员处理这些行更快地填充队列。

您应该尝试让一个线程读取文件,因为无论如何,多个线程都可能被I/O绑定。然后,您可以将这些行馈送到一个线程安全队列中,多个线程可以从该队列中取出要解析的行


您将无法告诉任何一个线程的进度,因为该线程没有定义的工作量。但是,您应该能够通过跟踪总共有多少项已添加到队列中以及有多少项已取出来跟踪大致进度。显然,当您的文件读取器线程将更多行放入队列时,由于有更多行可用,您的进度似乎会降低,但是,大概您应该能够比工人处理队列的速度更快地填充队列。

当其他海报说使用多线程的复杂性/困难可能会超过任何速度优势时,您肯定同意他们的看法……添加线程可以很好地提高读性能。我对此进行了基准测试。请参阅。好的,我最终结束了使用一个线程读取大文件,并创建了与用户配置的线程数量相同的文件。因此,如果用户设置了4个线程,我将这个大文件划分为4个不同的文件。一旦线程完成,我创建4个线程,每个线程读取不同的文件并处理每个记录。我还没有做过基准测试,但我会让你知道的。感谢大家的回复。当其他人说使用多线程的复杂性/困难可能会超过任何速度优势时,他们肯定同意他们的观点……添加线程可以很好地提高阅读性能。我对此进行了基准测试。请参阅。好的,我最终结束了使用一个线程读取大文件,并创建了与用户配置的线程数量相同的文件。因此,如果用户设置了4个线程,我将这个大文件划分为4个不同的文件。一旦线程完成,我创建4个线程,每个线程读取不同的文件并处理每个记录。我还没有做过基准测试,但我会让你知道的。谢谢大家的回复。说得很好,特别是最后一部分。事实上,数据的处理是最重要的。实际上,我现在正在做的是,主线程逐行读取文件,当每一行被消耗时,就会创建一个新线程,将该行传递给线程,以便它可以处理该信息。一旦一个线程完成,我就会触发一个事件,告诉我线程已经完成,这样我就可以创建一个新的线程,这样我就不会创建比用户指定的线程数更多的线程了。说得很好,特别是最后一部分。实际上,数据处理是最耗时的。实际上,我现在正在做的是,主线程逐行读取文件,当每一行被消耗时,就会创建一个新线程,将该行传递给线程,以便它可以处理该信息。一旦一个线程完成,我就会触发一个事件,告诉我线程已经完成,这样我就可以创建一个新的线程,这样我创建的线程数就不会超过用户指定的线程数 是可配置的