3

我正在编写一个多线程应用程序。在主线程上是主窗口,它是一个无模式对话框。当用户单击开始按钮时,它将创建一个新线程,该线程会长时间执行某些操作。在主线程上,它将创建一个新的无模式对话框来显示该新线程的状态,每个线程 1 个。我使用资源编辑器创建了一种模板对话框,并为状态设置了一个静态文本,其 ID 为 IDC_STATIC_NUMCYCLE。我在 OnIdle 函数期间轮询线程的状态。状态的更新仅适用于 1 个线程,但如果我产生更多的静态文本,所有的静态文本将不会更新,直到最后或者它是唯一一个仍在运行的线程。

宣言:

map<CSimDlg *, CSimulator *> simulations;

我的 OnIdle 功能:

BOOL CFGSim1App::OnIdle(LONG lCount)
{
CWinApp::OnIdle(lCount);

DWORD exitCode;
CString numOfCycle;

for (map<CSimDlg *, CSimulator *>::iterator iter = simulations.begin(); iter != simulations.end();)
{
    // skip already finished threads
    if (iter->second == NULL)
    {
        iter++;
        continue;
    }
    if (GetExitCodeThread(iter->second->m_hThread, &exitCode))
    {
        if (exitCode == 0)
        {
            delete iter->second;
            iter->second = NULL;

            if (IsWindow(iter->first->m_hWnd))
            {
                iter->first->SetDlgItemText(IDC_STATIC_SIMSTATUS, L"Simulation done");
            }
            else
            {
                iter = simulations.erase(iter);
            }
        }
        else
        {
            ULONG64 temp = iter->second->m_ul64NumOfCycle;

            if (temp % 10000 == 0)
            {
                numOfCycle.Format(_T("%d"), temp);
                iter->first->SetDlgItemText(IDC_STATIC_NUMCYCLE, numOfCycle);
            }

            iter++;
        }
    }
    else
    {
        iter++;
    }   
}

return TRUE;
}

我猜问题出在静态文本的 id 上。有没有办法解决这个问题?还是我需要为每个对话框声明一个不同的 id?还是其他地方的问题?

4

2 回答 2

1

(temp % 10000 == 0) 条件对我来说是可疑的。您假设温度将缓慢增加,以至于将检测到 10000 个标记。情况可能并非如此。如果您想减少 GUI 操作,则为每个线程引入一个“last count”变量,并且仅当 temp 足够大于此变量时才更新 GUI,然后将其设置为 temp。

顺便说一句,std::map如果您对容器所做的只是遍历它,并且不使用地图的特殊功能,那么您就不需要了。它也可能是一个列表std::pair,或者一些新结构的列表。这个新结构可以保存上面提到的最后一个计数变量。

于 2013-03-12T10:44:31.377 回答
0

你的逻辑对我来说似乎很好。文本更改后,MFC 可能需要重新绘制请求:

iter->first->SetDlgItemText(IDC_STATIC_NUMCYCLE, numOfCycle);
iter->first->Invalidate();

对不起,但目前我没有方便的 MFC 来测试......

于 2013-03-12T11:14:19.580 回答