>GetExitCodeThread を使わない良い方法があるのでしょうか?
MFCだとどうするのがよいのかちょっとわかりませんが、
一応WaitForSingleObjectで終了を待ことができます。
stopFlagがTRUEのときにスレッドが中断されるように作ってあるから
stopFlagをTRUEにしてから終了待機すればよいということです。
提示サンプルは m_bAutoDelete=TRUE のままスレッドが走り出す構造だから
スレッド終了時点で pThread は自動的に delete されてしまう。
その後は pThread->m_hHandle を取得できなくなるので、うまくいかなくて当たり前。
以下の形で作成し、問題なく動作するようになりました。
とりあえず、この件は解決としておきます。
みなさんありがとうございました。
if(hThread)
{
stopFlag = TRUE;
::WaitForSingleObject(hThread->m_hThread, INFINITE);
stopFlag = FALSE;
hThread = AfxBeginThread(WorkThread, this);
}
else{
hThread = AfxBeginThread(WorkThread, this);
}
>subaruさん
WaitForSingleObject を使う事で大分すっきりした形にする事ができました。
ありがとうございます。
>tetrapodさん
この作りですと、hThread がスレッド終了時に delete されてても、
WaitForSingleObject が WAIT_FAILED を返すだけですので、
動作的には問題ないかなと思い m_bAutoDelete=FALSE は省略しました。
> この作りですと、hThread がスレッド終了時に delete されてても、
> WaitForSingleObject が WAIT_FAILED を返すだけですので、
んなことはない。そもそも WaitFor... までたどり着けない可能性がある。
hThread が delete 済みである場合、その hThread を使って
hThread->m_hThread とするだけでアクセス違反になる可能性がある。
今アクセス違反になっていないのはたまたまと考える必要がある。
# hThread と書くとスレッドハンドルに見えるので書き方がよくない (指摘済み)
# どうせ書くなら pThread だろう (スレッドオブジェクトへのポインタなので)
なるほど、今の状態はたまたま上手くいってるだけだったのですね
変数のわかりにくさもご指摘ありがとうございます。
上でも書かれていたようですが、直接ではなかったので気づいていませんでした。
最終的に手直しして、以下のようにしました。
このままだとスレッド実行が一度だけの場合、delete が出来ていない設計なので、
デストラクタあたりに追加するのが普通なのでしょうか?
※InitDialogで初期化
hThread =NULL;
----------
if(pThread)
{
stopFlag = TRUE;
::WaitForSingleObject(pThread->m_hThread, INFINITE);
delete pThread;
pThread = NULL;
}
// スレッド実行
stopFlag = FALSE;
pThread = AfxBeginThread(WorkThread, this, THREAD_PRIORITY_NORMAL, 0,
CREATE_SUSPENDED);
pThread->m_bAutoDelete = FALSE;
pThread->ResumeThread();
※追記
デストラクタに delete を追加した場合、
スレッドがまだ動いてる状態で delete されるとアクセス違反になるようです・・・
もう少し考えて見ます。
デストラクタにdeleteだけじゃなく
if(pThread)
{
stopFlag = TRUE;
::WaitForSingleObject(pThread->m_hThread, INFINITE);
delete pThread;
pThread = NULL;
}
これ全部追加すればいい
ウインドウに関連した処理とかの場合はOnDestroyの方がいいかも。
ウインドウが破棄されるタイミングと
デストラクタが呼ばれるタイミングは同じではないので。
>ryoさん
なるほど、そもそも全部追加すればよかったわけですね。
簡単な事でした・・・
>subaruさん
OnDestroy に記述して正常に呼ばれていました。
デストラクタの呼ばれるタイミングの違いについては、また別途勉強してみます。