【发布时间】:2017-05-03 11:44:39
【问题描述】:
我在要异步运行函数的应用程序中使用std::async,并从该函数使用SendMessage 函数从工作线程与UI 对话。以下是 MFC 测试应用程序的摘录,演示了我在做什么:
LRESULT CStdAsyncProjDlg::OnUserPlusOne(WPARAM, LPARAM)
{
MessageBox("Message", "Hello World Again", MB_OK);
return 0;
}
// Function that contains the async work.
void TestAsync(HWND hDlg)
{
// Send a message to the UI from this worker. The WM_USER + 1 message
// handler is CStdAsyncProjDlg::OnUserPlusOne
SendMessage(hDlg, WM_USER + 1, 0, 0);
}
// This event is fired when a button is pressed on the MFC dialog.
void CStdAsyncProjDlg::OnBnClickedButton1()
{
MessageBox("Message", "Hello World", MB_OK);
std::async(std::launch::async, TestAsync, m_hWnd);
}
在 Visual Studio 2013 中,上述代码按预期工作。当我按下按钮时,我会看到一个显示“Hello World”的消息框,然后在该消息框上单击“确定”后,我会看到另一个显示“Hello World Again”的消息框。
我面临的问题是,将上述代码迁移到 Visual Studio 2015 编译器后,应用程序在 SendMessage 函数调用后挂起。
在线阅读(回复this question)提到std::future 的析构函数阻塞。我已更改 Visual Studio 2015 中的代码以存储从 std::async 返回的 std::future,这似乎解决了问题(应用程序没有挂起,我收到第二个消息框)。但是查看std::future 代码,我似乎看不出Visual Studio 2013 和2015 之间有什么不同。所以我的问题是std::async 的工作方式有什么改变会导致这种行为吗?
谢谢
【问题讨论】:
-
我很确定这是 2013 年的一个错误,因为
async返回的未来析构函数一直需要阻止。 This question 表现出相同的行为。 VS2013 对 C++11 的支持很差。 VS2015 更新 3 或 2017 更加合规。 -
啊,
async的美妙世界,阻塞期货和魔法死锁...试试 this presentation,大约 42:30。 -
不要尝试从单独的线程发送消息(),它很可能会阻塞。使用 PostMessage()
-
在处理未实现的 future 的析构函数时,Microsoft 不同意 c++ 世界的其他部分。因此,c++ 的这个领域是不可移植的。这是他们抑制技术进步的阴谋的一部分。
-
谢谢大家。非常感谢。
标签: c++ c++11 winapi visual-c++