0

処理に時間がかかるスレッドがあります。スレッドが終了するのを待っている間、別の「進行状況を表示」スレッドを開始します。このスレッドは、ビットマップを前後に切り替えるだけで、プログラムがデータを処理していることを示します。驚いたことに、このアプローチはまったく機能しませんでした。

私の「show progerss」スレッドは、メイン アクティビティの開始時に更新 (=実行中) を停止し、そのアクティビティの終了時に更新を開始します。これは私が望むものとほとんど反対です! WaitForSingleOBjectはほとんどの時間待機状態にあり、短時間ウェイクアップするため、この動作を予期する必要がありますか?

 // This is the main thread that does the actual work
 CWinThread* thread = AfxBeginThread(threadDoWork, this, THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED );
         thread->m_bAutoDelete = FALSE;
         thread->ResumeThread();

// before I start to wait on the above thread, I start this thread which will toggle image to show application is processing
 AfxBeginThread(ProgressUpdateThread, &thread_struct_param, THREAD_PRIORITY_NORMAL, 0 );

 // wait for the main thread now.
 DWORD dwWaitResult = WaitForSingleObject( thread->m_hThread, INFINITE );

 DWORD exitCode;
 ::GetExitCodeThread( thread->m_hThread, &exitCode );
 delete thread;

 // This thread toggles image to show activity 
 UINT ProgressUpdateThread(LPVOID param) 
 {
     CEvent * exitEvent = ((mystruct *)param)->exitEvent;
     MyView *view ((mystruct *)param)->view;

     int picture = 0;

     do
     {
         waitResult =  WaitForSingleObject( exitEvent->m_hObject, 100);

         if (waitResult == WAIT_TIMEOUT)
         {

            picture = toggle ? 1: 0;

             // invert
             toggle =  !toggle;

             View->Notify( UPDATE_IMAGE, picture );
         }
         else if (waitResult == WAIT_OBJECT_0)
         {
             return TRUE;
         }
     }
     while( 1);
 }

私のソリューションのもう 1 つの考慮事項は、実際の「DoWork」スレッド コードには触れたくないということです。それが、別のスレッドを使用して GUI を更新する理由でもあります。このアプローチを機能させることはできますか? GUI を更新する唯一の信頼できる方法は、実際の「DoWork スレッド自体」から更新することですか?

アプリケーションがアイドル状態の場合、「進行状況を表示」スレッドが完全にジョブを実行することを明確にしたいのですが、ワーカー スレッド操作を (スレッドの優先順位を下げて) 起動すると、更新 GUI スレッドは単純に実行を停止し、ワーカーが停止した場合にのみ再開します。終わります。

Windows 7 を使用しています。

4

2 に答える 2

0

Remy Lebeau は、メインの GUI スレッドが実際にはワーカー スレッドで待機していることを正しく指摘しました。ワーカーの gui-update スレッドが (明らかに) gui 関数を呼び出していたため、メインの GUI スレッドでブロックされていました。メインの GUI スレッドが待機状態またはブロック状態にある場合、3 番目のスレッドの SetWindowText() でさえそのスレッドを待機させることに気付きました。

私は PeekandPump() メカニズムを使用するのが好きではありません。設計上の臭いだと思いました。もともとは、真のマルチタスクではなかった初期のウィンドウ (win95 より前だと思います) で使用されていました。私の知る限り、これは現在使用すべきではありません。

私の解決策は、OP に投稿したコード全体を新しいスレッドに入れることでした。したがって、GUI でボタンをクリックすると、この脅威が作成され、すぐに返されます。このマスター ワーカー スレッドは他のスレッドを待機できるようになり、GUI がブロックされることはありません。完了すると、親ウィンドウにメッセージを投稿して通知します。アプリケーションが別のスレッドで処理されている場合、ビットマップは別の gui-update スレッドを使用して完全に変更されるようになりました。

于 2013-08-18T17:58:04.773 に答える