在一個大文件夾(約300,000個對象)上,FindNextFile最多可能需要20秒才能用一個文件進行響應。我假設有一些批量操作在後臺進行,但它使操作非常難以取消。有沒有辦法做一個異步的FindNextFile?
有沒有辦法在異步模式下運行FindNextFile,以便它可以被取消,如果信息不再需要?
Win7,x64,NTFS。
備註:一旦信息被Windows緩存了,FindNextFile似乎沒有這個問題。它只是第一次嘗試枚舉大文件夾中的文件。
在一個大文件夾(約300,000個對象)上,FindNextFile最多可能需要20秒才能用一個文件進行響應。我假設有一些批量操作在後臺進行,但它使操作非常難以取消。有沒有辦法做一個異步的FindNextFile?
有沒有辦法在異步模式下運行FindNextFile,以便它可以被取消,如果信息不再需要?
Win7,x64,NTFS。
備註:一旦信息被Windows緩存了,FindNextFile似乎沒有這個問題。它只是第一次嘗試枚舉大文件夾中的文件。
不,FindNextFile是同步的,沒有可比的異步功能。這種問題的通常解決方案是多線程。您需要兩個線程:應始終保持對用戶的響應的UI線程以及執行FindNextFile調用的工作線程。我會使用帶鎖定機制的隊列。邏輯會是這個樣子:
輔助線程:
FindFirstFile();
do
{
LockQueue();
AddFileToQueue();
UnlockQueue();
while (FindNextFile() && !UserCanceled());
SetAllFilesDone();
UI線程:
while (!UserCanceled() && !AllFilesDone())
{
LockQueue();
GetFileFromQueue();
UnlockQueue();
ProcessFile();
}
的IShellFolder :: EnumObjects是一個更快的查詢,如果你只是需要訪問一些文件,但slower on a network作爲FindNextFile的批io具有較少的網絡往返。無論使用與否,取決於您需要多少信息以及每個文件的延遲。
IShellFolder :: EnumObjects是一個用戶模式外殼擴展:它如何在不調用FindNextFile的情況下執行FindNextFile的等效操作? – 2012-08-16 06:43:04
它發出不同類型的查詢,只返回pidl,用於獲取需要額外調用IShellFolder的屬性,如IShellFolder :: GetAttributesOf。如果您打算跳過查詢中的大部分文件(例如,當您正在進行分頁時),那麼IShellFolder :: EnumObjects可以是一個更快的查詢。 – 2012-10-12 21:25:40
您在循環中調用FindNextFile,是否正確?爲什麼不把循環放在一個線程中(並允許用戶取消)? PS:我不知道任何Win32級別的緩存,除了SMB文件共享。 – paulsm4 2012-08-15 19:23:14
您是否嘗試過使用CancelSynchronousIo? – 2012-08-15 22:27:54
@ paulsm4 FindNextFile確實發出批量查詢:http://blogs.msdn.com/b/oldnewthing/archive/2006/04/07/570801.aspx snowdude:您希望每個文件有多少信息? – 2012-08-16 02:28:43