2013-09-21 2 views
2

Следующий код запуск в приложении блоков Windows Store интерфейс в течение 30 секунд, несмотря на тот факт, что цикл должен выполняться в отдельном потоке:Почему элемент работы пула потоков выполняется в потоке пользовательского интерфейса?

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 и через 30 секунд. Линия 4. За эти 30 секунд пользовательский интерфейс заблокирован, а представление Thread в Visual Studio показывает тот же поток (SHcore.dll) для всех точек останова. Я использую Windows 8 и Visual Studio 2012. Может кто-нибудь объяснить?

ответ

2

Билл Мессмер дал прекрасный ответ на MSDN. Короче говоря:

Объект делегата, созданный Callback, не является проворным, что означает, что он не может быть передан в поток пула потоков. Вместо этого этот поток получает прокси-сервер и вызывает его маршалируется обратно к объекту delgate в потоке пользовательского интерфейса. Билл также дал легкое решение проблемы.

Смежные вопросы