2016-11-16 85 views
-1

我爲多個後臺線程中的文件夾中的每個項目啓動IShellItemImageFactory :: GetImage方法。該代碼看起來像這樣:IShellItemImageFactory :: GetImage卡在多線程環境

HRESULT GetImage(IShellItemImageFactory* pImgFactory, 
       SIZE Size, COLORREF BkColor, HBITMAP *phbm) 
{ 
    if (pImgFactory == 0 || phbm == 0) 
     return E_POINTER; 
    *phbm = 0; 

    HBITMAP hBmp = 0; 
    HRESULT hr = pImgFactory->GetImage(Size, SIIGBF_BIGGERSIZEOK, &hBmp); 
    if (SUCCEEDED(hr) && hBmp) 
    { 
     *phbm = CPicture::StretchBitmap(hBmp, Size, BkColor); 
    } 

    return hr; 
} 

有時我有所有16個線程裏面卡住調用pImgFactory->的getImage爲不同的項目。他們都呆在同一個地方,這可以在提供的堆棧中看到。我檢查了不同的線程處理不同的項目。什麼可能是這種奇怪現象的原因? enter image description here 編輯: 在David Heffernan的迴應之後,我意識到IShellItemImageFactory接口本身可能不是線程安全的。我們的線程子系統自動將每個線程初始化爲STA(通過調用CoInitialize(0)函數)。但是,對於IShellItemImageFactory,我需要MTA線程。有沒有辦法發現IShellItemImageFactory的coclass CLSID,以便在註冊表中找到它的線程要求?

編輯2: 也許,我們的線程機制在某種程度上與問題有關。在這個特定的情況下,我們使用一個我們稱之爲「作業隊列」的引擎。它是非阻塞的FIFO隊列,哪些元素描述了一個工作。描述包含指向作業算法和作業數據的指針。通常(但不是必需的)主線程將作業放入隊列。線程池中的一個空閒線程可以從隊列中獲取元素並執行作業。這個機制對我們來說已經有好幾年了。但可能會影響圖標提取。可能是,我在定義圖標提取算法和數據方面還不夠精確。我不知道如何確定它。

+0

也許你的代碼不是線程安全的。也許你沒有初始化COM。也許別的東西是錯的。你沒有顯示一個MCVE。 –

+0

我可以假設你等待Mutant - '\ BaseNamedObjects \ C :: Users::AppData:Local:Microsoft:Windows:Explorer:thumbcache_idx.db!rwWriterMutex'。如果這真的是突變 - 我們可以看看KMUTANT.OwnerThread - 確定哪個線程持有它,以及他在做什麼。但是對於這個需要有好的調試器和技巧 – RbMm

+0

@RbMm:一個好的調試器提供自動死鎖支持(如WinDbg的[!locks](https://msdn.microsoft.com/en-us/library/windows/hardware/ff563980)。 aspx)命令)。 (關於個人記錄:如果你不想讓除了你自己以外的所有人看起來像個白癡,你的貢獻會更有幫助。) – IInspectable

回答

0

這種現象並非真正的僵局。它會在解壓縮文件夾中的子文件夾圖像時發生,而該文件夾不會被Windows緩存。假設有一個帶有20個子文件夾F1,F2,...,F20的文件夾F,其中每個子文件夾包含20個其他子文件夾和文件。如果文件夾F沒有被緩存,提取20個圖像的子文件夾可能需要15-25分鐘(在我的Win10 8核心計算機上)。所有圖像一旦被提取後,對該文件夾F中的圖像的重複請求被快速執行。