Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何编写使用回调函数的响应进度条?_Multithreading_Mfc_Windows 7_Visual C++_Unresponsive Progressbar - Fatal编程技术网

Multithreading 如何编写使用回调函数的响应进度条?

Multithreading 如何编写使用回调函数的响应进度条?,multithreading,mfc,windows-7,visual-c++,unresponsive-progressbar,Multithreading,Mfc,Windows 7,Visual C++,Unresponsive Progressbar,我有一个进度条,它使用来自第三方驱动程序的回调函数,在一个名为CFProgress的窗口中显示一个传统的进度条 CFProgress *cFM=new CFProgress(); theApp.m_cFM = cFM; cFM->Create(CFProgress::IDD); cFM->ShowWindow(SW_SHOW); thirdpartydriver->set_OnProgress(ProgressFuncC, (void *) cFM); thirdpartydr

我有一个进度条,它使用来自第三方驱动程序的回调函数,在一个名为CFProgress的窗口中显示一个传统的进度条

CFProgress *cFM=new CFProgress();
theApp.m_cFM = cFM;
cFM->Create(CFProgress::IDD);
cFM->ShowWindow(SW_SHOW);
thirdpartydriver->set_OnProgress(ProgressFuncC, (void *) cFM);
thirdpartydriver->DoReallyLongTask();
progressfunc
如下所示:

void _stdcall ProgressFuncC(CallbackDataType UserData, LongWord Operation, LongWord Progress, LongWord Total, Bool CanStop, Bool *Stop)
{
 char cMsg[100];
 sprintf_s(cMsg, 100, "Task Progress (%d%% completed).", Progress * 100 / Total);
 CFProgress *cFM;
 cFM = theApp.m_cFM;
 cFM->m_Prg1.SetPos(Progress * 100 / Total);
 cFM->m_lblMsg.SetWindowText(cMsg);
 cFM->UpdateWindow();
}
这在早期的操作系统上运行得很好,但Windows7一直抱怨在显示进度条窗口时应用程序没有响应。实际功能不受影响

有什么好方法可以让它对Windows更敏感

我是否可以将此添加到
progressfunc
代码中,并期望它能够解决问题,或者我只是在这里感到困惑:

MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{
    if (msg.message == WM_QUIT)
    {
        ::PostMessage(NULL, WM_QUIT, 0, 0L);
    }
    else
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

thirdpartydriver->doreally longtask()在主UI线程上运行

如果是,则在您将控制权返回到消息循环之前,您的windows不会响应

除非此循环正在运行,否则所有窗口都不会响应,如果长任务位于主线程上,则它将阻止此循环

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}

您最好的选择是移动
thirdpartydriver->DoReallyLongTask()编码到一个单独的线程中,并让回调函数将消息放入消息循环(通过
SendMessage
PostMessage
),然后处理该消息并更新进度条。

thirdpartydriver->DoReallyLongTask()确实在主UI线程上运行,因为代码中没有多线程。但是将进度条放在一个单独的线程中不是更简单吗?它可能更简单,但不会解决您的问题。要获得响应的UI,必须将控件返回到消息循环。这就是windows的工作方式。我对多线程技术还不熟悉-我在问题中添加了一些代码:“我可以将其添加到ProgressFuncC代码中吗…”您认为这可以解决无响应问题吗?是的,这会有帮助。将其设置为while循环而不是if,因为可能有多条消息。