我在我的基於C#的WPF應用程序中有一個文件列表:List<string> Files
。如何使這些IO讀取並行和高性能
Files
包含〜1,000,000個獨特的文件路徑。
我在我的應用程序上運行了一個分析器。當我嘗試執行並行操作時,由於IO限制,它是非常滯後的。它甚至落後於我的UI線程,儘管沒有調度員要他們(注意是兩行我已經標記爲關閉):
Files.AsParallel().ForAll(x =>
{
char[] buffer = new char[0x100000];
using (FileStream stream = new FileStream(x, FileMode.Open, FileAccess.Read)) // EXTREMELY SLOW
using (StreamReader reader = new StreamReader(stream, true))
{
while (true)
{
int bytesRead = reader.Read(buffer, 0, buffer.Length); // EXTREMELY SLOW
if (bytesRead <= 0)
{
break;
}
}
}
}
的這兩行代碼繼續我的整個輪廓測試運行的〜70%。我希望實現IO的最大並行化,同時保持性能,使其不會完全癱瘓我的應用程序的UI。沒有什麼影響我的表現。證明:使用Files.ForEach
不會削弱我的用戶界面,並且WithDegreeOfParallelism
也可以提供幫助(但是,我正在編寫一個應用程序,該應用程序應該用於任何PC,因此我不能假定此計算具有特定的並行度);另外,我所在的個人電腦上有一個固態硬盤。我搜索了StackOverflow,並找到了使用異步IO讀取方法的鏈接。不過,我不確定他們在這種情況下是如何應用的。也許有人可以擺脫一些光明?也;你如何調整一個新的FileStream的構造函數時間;這甚至有可能嗎?
編輯:好吧,這裏有一些奇怪的東西,我已經注意到了......當我在使用AsParallel的同時將Read讀取爲ReadAsync時,UI不會被壓壞。簡單地等待由ReadAsync創建的任務完成後,會導致我的UI線程保持某種程度的可用性。我認爲這樣做是爲了在不破壞現有線程的情況下維持最佳的磁盤使用率而在此方法中完成的某種異步調度。在那個筆記上,操作系統有沒有機會爭奪現有的線程來執行IO,比如我的應用程序的UI線程? 我真的不明白爲什麼它減慢我的UI線程。操作系統調度是從我的線程上的IO或其他什麼工作?他們是否對CLR做了些什麼來吃掉沒有明確地使用Thread.BeginThreadAffinity
之類的線?記憶不是問題;我正在看任務管理器,有很多。
定義「非常」緩慢。您知道磁盤讀取速度比從RAM讀取速度慢100,000,000倍嗎? – aquinas 2014-11-08 07:32:24
你只是檢查文件是否存在?如果你是我會寫我自己的搜索。將所有文件名放入列表中。然後從基本目錄開始,並通過所有目錄進行遞歸搜索。找到文件時,將其從列表中刪除。然後,您可以返回尚未從列表中刪除的文件列表。如果你不嘗試這個,你應該更多地解釋你正在努力完成的事情。 – deathismyfriend 2014-11-08 07:33:18
@deathismyfriend不;我正在閱讀內容。我有一個關於「存在」問題的帖子:http://stackoverflow.com/questions/26321366/fastest-way-to-get-directory-data-in-net雖然這很容易,但速度非常快,但是沒有,這不是我想要/需要的。 – Alexandru 2014-11-08 07:39:56