複数のスレッドを立ち上げ処理を行うSDIアプリを作成しています。
現在、各スレッドからドキュメントに値を設定し、
メインスレッド側のタイマー処理で描画の更新を行っています。
// スレッド処理(自前のスレッドクラス)
void Cthrd::Write(){
pDoc->xxxWrite("aaaa");
}
// ドキュメント
CTradeBoyDoc::xxxWrite(LPCTSTR pszData){
EnterCriticalsection(..);
strcpy(m_pszData,pszData);
LeaveCriticalsection(..);
}
// メインフレーム
CMainFrame::OnTimer(UINT nIDEvent){
GetActiveDocument()->UpdateAllViews(NULL);
}
この処理で動くことは動くのですが、
プログラムが下手な気がしてなりません。
(更新していないときも定期的に描画が呼び出されたり・・)
素人質問で申し訳ないのですが、
こういう場合の最も一般的なコーディングをご教授お願いいたします。
> こういう場合の最も一般的なコーディングをご教授お願いいたします。
一般的かどうかはわかりかねますが、とりあえず簡単な方法として、
各スレッドでデータを変更し、ビューの表示を更新して欲しいタイミングで、
メインフレーム対して独自追加した更新要求メッセージを送る。
で、メインフレーム側の独自追加した更新要求メッセージの中で、
たとえば、例示されているOnTimer()の中の処理を実行するとか、
いかがでしょうか?
これなら少なくとも、
>(更新していないときも定期的に描画が呼び出されたり・・)
はありませんので。
CDocument::UpdateAllViews とか、CView::OnUpdate とか。
編集 削除あぁ、勘違い…orz。
KING・王 さんの方法がよい気がします。
KING様
返信ありがとうございます。
当初、メッセージを送信(post)して描画を行っていたのですが、
クリティカルセクションが突然抜けなくなる問題がありました。
原因はわからなかったのですが、
PostMessageを行わないようにすることにより解決でき、
問題のPostMessageもクリティカルセクションとは関係なく、また使用しているクリティカルセクションのパスも1つのみであるため、メッセージの送信事態に問題を感じて、現在の形としました。
(Message受信側では、invalidateを実行していましたので、それが原因な気がしています。)
追加の質問で恐縮ですが、
別スレッドからPostMessageを行うことに問題はないのでしょうか。
> 別スレッドからPostMessageを行うことに問題はないのでしょうか。
問題ありません。
> クリティカルセクションが突然抜けなくなる問題がありました。
# デッドロックっぽいですね…。
> 問題ありません。
問題があって欲しかったです。^^;
> デッドロックっぽいですね…。
デットロックなのですが、
TRACEで行ごとに追ってみても原因がわかりませんでした。
(LeaveCriticalsectionに着く前に、制御が突然戻ってこなくなりました。)
関係ないPostMessageを削除すると動作するようになったため
そのあたりに原因を求めたのですが。。。
とりあえず、普通はpostmessageを使用できるということがわかりよかったです。ソースを書き進めてしまったので今回はOntimerでいきますが、次回引っかかったときは、もっと根詰めてデバックします。
Ben様 King様、ありがとうございました。