join 阻塞当前线程,直到另一个线程完成,所以这没有帮助。
您应该启动工作线程,立即返回和工作线程
完成后应该发送某种消息。
您的示例代码中的函数名称看起来像是来自 MSVC++ MFC
应用程序,所以我们将使用它。
简单地说,Windows GUI 应用程序是事件驱动的,每次事件发生时
WM_MESSAGE 已发送。框架接收这些消息并调用适当的
处理它的功能。我们可以定义自己的消息和消息处理程序。
这样,工作线程可以将此类消息发送到框架,并且它将调用
我们的处理函数。
WM_APP 被定义为私人用户消息的起点,所以不会有
与现有系统消息的任何冲突。
(https://msdn.microsoft.com/en-us/library/windows/desktop/ms644930%28v=vs.85%29.aspx)
因此,假设我们正在构建一个 MFC 对话框应用程序,用于搜索文件中的内容。
如果文件很大,则可能需要很长时间并防止阻塞主线程和
收到“窗口没有响应”消息,我们需要在工作线程中执行此操作。我们可能
例如,还想要一个进度条。
首先,我们在现有的对话框类中定义自己的消息,从 WM_APP + 1 开始
我们添加我们的处理函数,它们必须是以下类型:
afx_msg LRESULT (CWnd::*)(WPARAM, LPARAM)
WPARAM 和 LPARAM 是发布消息时传递的参数,可以使用它们来发送
自定义数据。在我们的示例中,我们可以使用它们来发送进度条的 % 进度。
(https://msdn.microsoft.com/en-us/library/k35k2bfs.aspx)
class CMyAppDlg : public CDialogEx
{
public:
//Public so the worker thread class can use these same sames when posting a message.
enum Messages
{
MSG_ThreadProgress = WM_APP + 1,
MSG_ThreadDone
};
private:
afx_msg LRESULT OnThreadProgress(WPARAM wParam, LPARAM lParam)
{
ProgressBar->SetPos(wParam); //Worker thread posts progress as wParam
};
afx_msg LRESULT OnThreadDone(WPARAM wParam, LPARAM lParam)
{
//Get result from worker thread class and use it...
};
};
然后我们需要将我们的消息和处理程序添加到消息映射中,您应该将它们添加到已经
对话框/文档的 .cpp 文件中的现有消息映射。
BEGIN_MESSAGE_MAP(CMyAppDlg, CDialogEx)
ON_MESSAGE(MSG_ThreadProgress, &CMyAppDlg::OnThreadProgress)
ON_MESSAGE(MSG_ThreadDone, &CMyAppDlg::OnThreadDone)
END_MESSAGE_MAP()
现在我们可以简单地将这些消息发布到我们的工作线程中,框架主线程将处理
消息并更新进度条或使用结果:
class ThreadClass
{
public:
//Constructor takes a reference to our dialog class because we need the window handle
//to post a message
ThreadClass(CMyAppDlg& MyAppDlg) : mMyAppDlg(MyAppDlg) {};
void operator()() //Thread worker code...
{
while (what_we_look_for_not_found)
{
int Progress = 0;
//Search for a while and update progress variable...
//Post message to dialog asking it to update the progressbar
PostMessage(mMyAppDlg.m_hWnd, CMyAppDlg::MSG_ThreadProgress, Progress, 0);
}
//Finished searching...
StoreResult();
//Post message to dialog informing it thread is done and result can be retrieved.
PostMessage(mMyAppDlg.m_hWnd, CMyAppDlg::MSG_ThreadDone, 0, 0);
}
private:
CMyAppDlg& mMyAppDlg;
};
QT 使用与 SIGNAL 和 SLOT 类似的系统,其他框架肯定有自己的等效系统。
如果您使用的不是 MSVC++ MFC,您应该能够在手册中找到更多信息。