【问题标题】:Why is thread pool work item executed on UI thread?为什么线程池工作项在 UI 线程上执行?
【发布时间】:2013-09-21 22:53:20
【问题描述】:

尽管循环应该在单独的线程中运行,但在 Windows 应用商店应用程序中运行的以下代码会阻塞 UI 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 秒内,UI 被阻止并且 Visual Studio 中的线程视图显示所有断点的相同线程(SHcore.dll)。 我正在使用 Windows 8 和 Visual Studio 2012。 谁能解释一下?

【问题讨论】:

    标签: multithreading windows-runtime winrt-async wrl


    【解决方案1】:

    Bill Messmer 在MSDN 上给出了完美答案。简而言之:

    Callback 创建的委托对象不是敏捷的,这意味着它不能传递给线程池线程。取而代之的是,该线程接收一个代理并将对其的调用编组回 UI 线程中的 delgate 对象。 Bill 还给出了一个简单的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-02
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      • 2022-01-10
      • 2018-06-22
      • 2016-01-16
      相关资源
      最近更新 更多