2009-09-16 46 views
1

我google搜索关于这个一些建议,我发现了一些链接。最明显的是this one,但最后我想知道的是我的代码实现得如何。阅读从多个线程相同的文件在C#中

我基本上有两类。一个是转换,另一个是ConverterThread

我创建一个具有属性ThreadNumber,告诉我有多少线程应该在同一时间运行该转换器类的一个实例(这是从用户读取)因为这个应用程序将用于多CPU系统(物理上,如8 cpu),所以它是suppossed,这将加速导入

该转换器实例读取一个文件,范围可以从100MB到800MB,每行此文件是一个制表符分隔的值记录,它被导入到另一个目标,如数据库。

ConverterThread类只是在线程内运行(新线程(ConverterThread.StartThread))并且有事件通知,所以当它的工作完成后它可以通知Converter类,然后我可以总结所有这些线程的进度,通知用户(例如在GUI中)已经导入了多少个这样的记录以及已经读取了多少个字节。

然而,我有一些麻烦,因为我得到有关该文件不能被读取的随机错误,或进度(百分比)的总和超过100%,这是不可能的,我认为发生这种情况是因为线程管理不善,并且可能由事件返回的信息格式错误(因为它从一个线程“传播”到另一个线程)

您有任何关于线程实现的更好实践的建议,所以我可以完成这个?

在此先感谢。

+0

肯定与其他海报的情绪同意时,他们说,使用多线程的复杂性/难度可能会超过任何速度优势...... –

+0

添加线程可以很好地提高读取性能。我以此为基准。请参阅http://stackoverflow.com/questions/1033065/will-using-multiple-threads-with-a-randomaccessfile-help-performance/1254378#1254378。 –

+0

好了,所以我最后用一个单独的线程来读取大文件和创造尽可能多的文件,主题配置,所以如果用户设置4个线程我把4个不同的文件,这个大文件的用户结束。一旦线程完成,我创建4个线程,每个线程读取不同的文件并处理每条记录。我没有基准测试,但我会让你知道。感谢所有的答复。 –

回答

10

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

既然你从来没有引用的文章的作者实际上提供的“真实”的代码,他声称,多线程将加快I/O仍然被别人不可测。任何通过添加线程来提高硬盘读/写性能的尝试肯定会受到I/O限制,除非他在读取之间进行了一些严重的数字处理,或者偶然发现了与磁盘缓存有关的一些令人高兴的巧合,其中在另一台具有不同硬件特性的机器上,性能改进可能无法实现。

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

在使用线程来做到这一点之前,我仔细地对软件进行了基准测试,以确定线程是否会真正提高整体吞吐量。测试结果(在我的开发机器上)是使用与处理器内核的数量相同的线程数量来产生最大可能的吞吐量。但是这是每个线程处理一个文件。

+0

+1,线程不是这里的答案。 –

10

多个线程在同一时间读取文件是自找麻烦。我将建立一个生产者消费者模型,以便生产者读取文件中的行,也许将其写入缓冲区,然后在完成处理当前工作负载时将它们交给消费者线程。这确实意味着你有一个阻碍点,但是如果处理花费的时间比阅读时间长得多,那么它不应该是一笔大交易。如果阅读是缓慢的部分,那么你真的不需要多个消费者。

+0

很好说,特别是最后一部分。 – Josh

+0

其实数据的处理是最需要的。事实上,我现在正在做的是主线程逐行读取文件,并且每消耗一条线,创建一个新线程将该线传递给线程,以便它可以处理该信息。一旦线程完成,我启动一个事件,告诉我线程已完成,因此我可以创建一个新线程,以便不创建比用户指出的更多的线程(线程数可配置) –

0

你应该尝试只是有一个线程读取该文件,因为多个线程可能会被我约束/ O反正。然后,您可以将这些行提供给一个线程安全的队列,多个线程可以从中排队线路以进行解析。

您将不能告诉任何一个线程的进度,因为线程没有定义的工作量。但是,您应该能够追踪近似进度,方法是跟踪已添加到队列中的项目数(总计)以及已取出的项目数。很显然,随着文件读取器线程将更多行放入队列中,您的进度看起来会减少,因为有更多的行可用,但可以推测,您应该能够比工作人员处理行更快地填充队列。