3

マルチスレッドアプリを書いています。メインスレッドには、モードレスダイアログボックスであるメインウィンドウがあります。ユーザーがスタートボタンをクリックすると、長い間いくつかのことを行う新しいスレッドが作成されます。メインスレッド上に、新しいモードレスダイアログボックスが作成され、その新しいスレッドのステータスがスレッドごとに1つ表示されます。リソースエディタを使用して一種のテンプレートダイアログボックスを作成し、ステータスの静的テキストをIDC_STATIC_NUMCYCLEのIDに設定しました。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 個のマークが検出されるほど十分にゆっくりと temp が増加すると想定しています。そうではないかもしれません。GUI 操作を減らしたい場合は、スレッドごとに「最後のカウント」変数を導入し、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 に答える