2009-09-16 44 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反正。然後,您可以將這些行提供給一個線程安全的隊列,多個線程可以從中排隊線路以進行解析。

您將不能告訴任何一個線程的進度,因爲線程沒有定義的工作量。但是,您應該能夠追蹤近似進度,方法是跟蹤已添加到隊列中的項目數(總計)以及已取出的項目數。很顯然,隨着文件讀取器線程將更多行放入隊列中,您的進度看起來會減少,因爲有更多的行可用,但可以推測,您應該能夠比工作人員處理行更快地填充隊列。