2012-08-15 63 views
2

在一個大文件夾(約300,000個對象)上,FindNextFile最多可能需要20秒才能用一個文件進行響應。我假設有一些批量操作在後臺進行,但它使操作非常難以取消。有沒有辦法做一個異步的FindNextFile?

有沒有辦法在異步模式下運行FindNextFile,以便它可以被取消,如果信息不再需要?

Win7,x64,NTFS。

備註:一旦信息被Windows緩存了,FindNextFile似乎沒有這個問題。它只是第一次嘗試枚舉大文件夾中的文件。

+0

您在循環中調用FindNextFile,是否正確?爲什麼不把循環放在一個線程中(並允許用戶取消)? PS:我不知道任何Win32級別的緩存,除了SMB文件共享。 – paulsm4 2012-08-15 19:23:14

+0

您是否嘗試過使用CancelSynchronousIo? – 2012-08-15 22:27:54

+0

@ paulsm4 FindNextFile確實發出批量查詢:http://blogs.msdn.com/b/oldnewthing/archive/2006/04/07/570801.aspx snowdude:您希望每個文件有多少信息? – 2012-08-16 02:28:43

回答

2

不,FindNextFile是同步的,沒有可比的異步功能。這種問題的通常解決方案是多線程。您需要兩個線程:應始終保持對用戶的響應的UI線程以及執行FindNextFile調用的工作線程。我會使用帶鎖定機制的隊列。邏輯會是這個樣子:

輔助線程:

FindFirstFile(); 
do 
{ 
    LockQueue(); 
    AddFileToQueue(); 
    UnlockQueue(); 
while (FindNextFile() && !UserCanceled()); 
SetAllFilesDone(); 

UI線程:

while (!UserCanceled() && !AllFilesDone()) 
{ 
    LockQueue(); 
    GetFileFromQueue(); 
    UnlockQueue(); 
    ProcessFile(); 
} 
1

的IShellFolder :: EnumObjects是一個更快的查詢,如果你只是需要訪問一些文件,但slower on a network作爲FindNextFile的批io具有較少的網絡往返。無論使用與否,取決於您需要多少信息以及每個文件的延遲。

+0

IShellFolder :: EnumObjects是一個用戶模式外殼擴展:它如何在不調用FindNextFile的情況下執行FindNextFile的等效操作? – 2012-08-16 06:43:04

+0

它發出不同類型的查詢,只返回pidl,用於獲取需要額外調用IShellFolder的屬性,如IShellFolder :: GetAttributesOf。如果您打算跳過查詢中的大部分文件(例如,當您正在進行分頁時),那麼IShellFolder :: EnumObjects可以是一個更快的查詢。 – 2012-10-12 21:25:40

相關問題