2013-09-21 41 views
2

在Windows商店應用塊下面的代碼運行的UI 30秒,儘管這個循環還應當在一個單獨的線程中運行:爲什麼線程池工作項目在UI線程上執行?

int seconds(30); 
// Create a thread pool 
ComPtr<IThreadPoolStatics> threadPool; 
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), &threadPool); 
// 
// Create an asynchronous task and start it 
ComPtr<ABI::Windows::Foundation::IAsyncAction> asyncActionPtr; 
hr = threadPool->RunAsync(Callback<IWorkItemHandler>(// Line 1 
    // 
    // Lambda for task. Loops doing nothing until 30 seconds have passed 
    [seconds](ABI::Windows::Foundation::IAsyncAction* asyncAction) -> HRESULT { 
     std::chrono::system_clock::time_point end(std::chrono::system_clock::now() + std::chrono::seconds(seconds)); // Line 3 
     while (std::chrono::system_clock::now() < end); 
    return S_OK; // Line 4 
}).Get(), &asyncActionPtr); 
if (FAILED(hr)) throw std::exception("Cannot start thread"); // Line 2 

當我設置的標線斷點,我可以看到,第1行命中第2行,然後是第3行,之後是第3行30秒。在這30秒內,UI被阻止,並且Visual Studio中的線程視圖爲所有斷點顯示相同的線程(SHcore.dll)。 我正在使用Windows 8和Visual Studio 2012. 有人可以解釋嗎?

回答

2

Bill Messmer給出了MSDN的完美答案。總之:

由Callback創建的委託對象不是敏捷的,這意味着它不能傳遞給線程池線程。相反,該線程收到一個代理並將其調用回UI線程中的delgate對象。比爾還爲這個問題提供了一個簡單的解決方案。