VC++のMFCを使ってダイアログベースのEXEを造っています。
ハンドルのリークが発生し、困っています。

<動作内容>
メインのダイアログで、ボタン押下により別のダイアログを表示します。
DoModal()でモーダルダイアログを作成します。
別のプロセスからブロードキャストされるメッセージを処理したいため、
ボタン押下のルーチンで DoModal() せずに、スレッドを作成し、
そのスレッドで DoModal() を実行しています。
スレッド作成は AfxBeginThread() を使用しています。

<サンプルソース>
●メインダイアログ
// ボタン押下のルーチン
void CTestModalDlg::OnButton1()
{
AfxBeginThread( TestDlgThread, (LPVOID)this,
THREAD_PRIORITY_NORMAL );
}

// スレッド
static UINT TestDlgThread(LPVOID pThis)
{
CTestDlg1 Dlg;
Dlg.DoModal();
}

●DoModal() で表示されるダイアログ
何も手を加えてない、デフォルトのまま。

<結果>
DoModal() で表示されたダイアログを CDialog::OnCancel() で終了させ、
メインのスレッドが終了しても、ハンドルカウントが1つ増加しています。
Sleep() を入れて値をみてみると、
・スレッド作成:2増加
・DoModal() でダイアログ表示:1増加
・OnCancel() で終了:増減なし
・スレッド終了:2減少
=>結果、1増加となっていました。

以下のパターンでは問題ありませんでした。
・スレッドを作成+終了(ダイアログ表示しない)
・スレッドを作成せずに、ボタン押下ルーチンから
DoModal() でダイアログ表示+終了

ということで、AfxBeginThread()、DoModal() 自体は問題ないのですが、
スレッドを作成して DoModal() するとリークが発生します。

識者の方、原因、対策など、ご教授願います。

A 回答 (2件)

//メンバ変数として


CDialog* m_pDlg;

void CTestModalDlg::OnButton1()
{
if(m_pDlg==NULL){
m_pDlg=new CDialog;
m_pDlg->Create(IDD_DIALOG1);
m_pDlg->ShowWindow(SW_SHOW);
}
}

void CTestModalDlg::OnDestroy()
{
CDialog::OnDestroy();

if(m_pDlg!=NULL){
delete m_pDlg;
}
}
こんな感じでモードレスダイアログできますよ。
じゃ。
    • good
    • 0
この回答へのお礼

アドバイスありがとうございました。
なぜか、Create()、ShowWindow()してもダイアログが表示されませんでした。
メインのダイアログはアクティブな状態だったので、仕方なくキャンセルボタンを
押したらアプリケーションエラーになってしまいました。
デバッグしようと思ってステップ実行させたら、ちゃんとダイアログが表示されました。
不思議。。。
頑張ってやってみます。
いつも適切なアドバイスありがとうございます。

お礼日時:2001/07/13 19:04

TestDlgThread関数の戻り値がないからでは、ないですか?


てゆうか、モーダルダイアログじゃなくて、モードレスダイアログを作ったらどうでしょう?

この回答への補足

すいません、記述もれです。
スレッドの関数では「return(0);」しています。
スレッドからモーダルダイアログを作成しているのは以下の理由です。
・操作できるダイアログは一番上の(DoModalで作成された)ダイアログだけ
・DoModalで作成されたダイアログが閉じられたタイミングで(Domodal関数が
戻ってきた時)、処理をしたい。
・メインのスレッドでは、他のプロセスからのメッセージを受信したい

#「スレッド+モーダル」だけNGというのが解せないです。。。

あと、追加の質問のようになってしまい申し訳ないのですが、
モードレスダイアログの作成についてご存知でしたら教えてください。

サンプルソースを以下のようにしました。
IDD_DIALOG1 は、DoModal で表示しようとしていた CTestDlg1 クラスの
ダイアログのIDです。

void CTestModalDlg::OnButton1()
{
CDialog::Create( IDD_DIALOG1, NULL );
}

しかし、実行したところ Create() で落ちてしまいました。
単純に Create() だけでは駄目でしょうか?

補足日時:2001/07/12 10:13
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q道に迷わない地図の読み方(極度の方向音痴)

こんにちは。私は、現在大学4年で今年の春からメーカーの営業職として勤務をする予定です。しかし、私は困ったことに極度の方向音痴なのです。就職活動中も地図を持っていながら必ず迷っていました。駅の改札を出発点として「どっちがどっち?こっちは東口?西口?」とか、進む方向が分かっても地図を進む方向に返したりしていました。この段階では、まだ徒歩なのでいいのですが、営業職では車を使いますのでなおさら不安です。そして、毎日広範囲の領域(いくつかの県をまたぐ)を担当します。親や友人、就職先の社員の方に相談しても「慣れてしまえば大丈夫」と言われていますが・・・・慣れるまでが不安です。そこで
、地図を読むのが得意な人や、営業職で同じように車を使って仕事をしている方、道に迷った記憶がないという方がいましたらアドバイス(地図の読み方など)お願いします。なお、カーナビが無いということを前提でお願いします。

ちなみに私の地図の読み方は,
(1)まず自分の現在地を確認
(2)目的地を確認
(3)目的地は、どちらの方向にあるのか考える(これが苦手で、
目印の建物を探すのですが・・それでもパニックになります)
(4)遠回りしてもいいから大きな道路や分かりやすい道を選択して
進む。

です。以上よろしくお願いします。

こんにちは。私は、現在大学4年で今年の春からメーカーの営業職として勤務をする予定です。しかし、私は困ったことに極度の方向音痴なのです。就職活動中も地図を持っていながら必ず迷っていました。駅の改札を出発点として「どっちがどっち?こっちは東口?西口?」とか、進む方向が分かっても地図を進む方向に返したりしていました。この段階では、まだ徒歩なのでいいのですが、営業職では車を使いますのでなおさら不安です。そして、毎日広範囲の領域(いくつかの県をまたぐ)を担当します。親や友人、就職先の社...続きを読む

Aベストアンサー

10年ほど、車を使って営業をしていました。

まず、道は間違えるもの・迷うものであると思ってください。一度覚えた道でも、何のガイドもなしに久しぶりに走れば間違います。
間違えを繰り返しながら、道を覚えましょう。ちなみに営業適正と方向音痴は何の関係もありません。営業に必要なのは営業力ですからね。取引先の方との信頼関係を築ける力のほうが遥かに大事です。

地図は営業テリトリーの広さに合わせて持つことが大事です。私は最も多い時は、東京都・千葉県・埼玉県・神奈川県のA4版の地図と東京の持ち歩きようポケット地図を車に入れていました。

営業ですから一日に何箇所も回ると思います。

(1)あらかじめ一日の行動が全て決まってる場合は、前日に全てのルートを地図でチェックしましょう。メモに書き写して、確認しながら運転しましょう。この手間が大事です。その場合、道の名前と曲がる交差点名を記します。
  第一目的地→青梅街道→四街道交差点右折→環状八号線→
  高井戸交差点右折→R20→3つめの交差点右折→第二目的地
曲がるまでにどれくらいの距離を走るかまで記しておくと完璧です。
すぐに曲がる場合や、かなり直線を走る場合などは疑心暗鬼になります。

(2)出先で次の行き先が変更される場合は、時間に余裕があれば上記の要領でメモで書き出しましょう。時間の余裕が無ければ、目的地へのルートを蛍光ペンで塗りましょう。数ページにわたる場合は、そのページの上にポストイットを貼りましょう。必然的に蛍光ペンとポストイットは車内常備が必須となります。これは結構便利ですよ。ポストイットは運転中の急な連絡の時にメモとしても使えますからね。大き目のポストイットを用意したほうがよいでしょう。
蛍光ペンで塗られる道がどんどん多くなりますが、その度に道を覚えられると思います。

10年ほど、車を使って営業をしていました。

まず、道は間違えるもの・迷うものであると思ってください。一度覚えた道でも、何のガイドもなしに久しぶりに走れば間違います。
間違えを繰り返しながら、道を覚えましょう。ちなみに営業適正と方向音痴は何の関係もありません。営業に必要なのは営業力ですからね。取引先の方との信頼関係を築ける力のほうが遥かに大事です。

地図は営業テリトリーの広さに合わせて持つことが大事です。私は最も多い時は、東京都・千葉県・埼玉県・神奈川県のA4版の地図と東京...続きを読む

Qダイアログのボタンが押された時に、その「ボタン」のあるダイアログと、すでに表示されている他のダイアログを消したいです

Win2000/MFC/ダイアログベース
で作業しています。初心者です(^^;)

Aというダイアログで「あるボタンa」を押してDoModalでBというダイアログを表示させ、Bダイアログで「あるボタンb」を押してDoModalでCというダイアログを表示させ、Cダイアログで「あるボタンc」を押した時にBダイアログとCダイアログを閉じたい(消したい)のですが
EndDialogで消せません
DoModalの戻り値をret_b,ret_cとした場合
EndDialog(ret_c);
EndDialog(ret_b);
としたのですが。。。

やり方がおかしいのか、よくわかりません・・
初心者でもわかりやすいお返事お待ちしています(^^;)

Aベストアンサー

各ダイアログボックスを CDialog の派生クラスとして次のように定義したとします。

CDlgA --- A というダイアログボックス
CDlgB --- B というダイアログボックス
CDlgC --- C というダイアログボックス

CDlgA のあるメンバ関数から CDlgB::DoModal() でダイアログボックス B を表示させます。 CDlgB のあるメンバ関数で EndDialog() を実行すればダイアログボックス B を閉じることができます。ここで、 CDialog::EndDialog() は引数として INT 型の値をひとつ渡すことができますが、その値が先の CDlgB::DoModal() の戻り値となります。
戻り値がある特定の値だったとき、つまり、質問の例ではダイアログボックス B で EndDialog(ret_b) が実行されたことが特定できたときに CDlgA も EndDialog() を実行すれば連鎖してダイアログボックスを閉じることができます。
ダイアログボックス C についても同様です。

実際のコーディングでは次のようになると思います。
ただし、ダイアログボックス A もモードレスで表示されていると仮定しています。



#define ret_b (-1) // 特定の値
#define ret_c (-1) // ID_OK や ID_CANCEL と重ならないように注意

...

(CDlgA の実装)

void CDlgA::OnButtonA() // あるボタン a が押されたときの処理
{
CDlgB dlg; // ダイアログボックス B

if (dlg.DoModal() == ret_b) // モードレスで表示して、戻り値をチェック
EndDialog(-1); // ダイアログボックス A を閉じる
}

...

(CDlgB の実装)

void CDlgB::OnButtonB() // あるボタン b が押されたときの処理
{
CDlgC dlg; // ダイアログボックス C

if (dlg.DoModal() == ret_c) // モードレスで表示して、戻り値をチェック
EndDialog(ret_b); // ダイアログボックス B を閉じる
}

...

(CDlgC の実装)

void CDlgC::OnButtonC() // あるボタン c が押されたときの処理
{
EndDialog(ret_c); // ダイアログボックス C を閉じる
}

各ダイアログボックスを CDialog の派生クラスとして次のように定義したとします。

CDlgA --- A というダイアログボックス
CDlgB --- B というダイアログボックス
CDlgC --- C というダイアログボックス

CDlgA のあるメンバ関数から CDlgB::DoModal() でダイアログボックス B を表示させます。 CDlgB のあるメンバ関数で EndDialog() を実行すればダイアログボックス B を閉じることができます。ここで、 CDialog::EndDialog() は引数として INT 型の値をひとつ渡すことができますが、その値...続きを読む

Q万博公園まで迷わない方法

大阪万博公園まで行くのに三重の津駅から近鉄の特急を使うことにしたんですが、特急をどこで降りて、そのあとどの路線つかえばいいですか?最終的にモノレールがあるみたいなんでそれを使いたいんです。お願いします<(_ _)>

Aベストアンサー

 上本町・難波行きに乗れば難波まで直通です。
また、賢島行き特急に乗って、中川で乗り換える手もありますが、津から難波行きに乗るのがいいでしょうね。

難波からは大阪市営地下鉄の御堂筋線に乗り換え、千里中央方面行に乗り、終点千里中央で大阪モノレールに乗り換えます。

 たとえば
 津9:20→大阪難波10:56 およそ100分 1640円+1280円(特急料金)
なんば→千里中央 およそ30分 390円
千里中央→万博記念公園 乗り換え含めて15分 240円

 なんばからの地下鉄は数分おきに出ているので時刻表は書きません。

 スムーズに行けば、津で特急に乗ってから2時間45分、3550円です。

Qダイアログを継承したダイアログの作成について

お世話になります。
今回お聞きしたいことは、
オリジナルに作成したダイアログを継承したオリジナルのダイアログを作成した際に、オリジナルに作成した基底ダイアログのダイアログ上のコントロールや、そのコントロールの位置を継承することはできますでしょうか?
ということです。
何がしたいかといいますと、4つのダイアログをメインダイアログから呼び出すのですが、その4つのダイアログには共通するコントロールがあり、そのコントロールの動作もその位置も全く同じなのです。
そのため、いちいち4つのダイアログにコントロールの貼り付けや、処理を記入せずに、その共通のコントロールをもった基底ダイアログを作成して、その基底ダイアログの継承としてダイアログが作れたらなと思い、質問させて頂きました。
継承をすると、基底クラスの関数等を使うことができるというのはわかるのですが、ダイアログ上のコントロールの位置までは不可能なのかなと疑問に思いました。
ご回答を宜しくお願い致します。

開発環境は
Windows CE 6.0
Visual Studio 2005
です。

お世話になります。
今回お聞きしたいことは、
オリジナルに作成したダイアログを継承したオリジナルのダイアログを作成した際に、オリジナルに作成した基底ダイアログのダイアログ上のコントロールや、そのコントロールの位置を継承することはできますでしょうか?
ということです。
何がしたいかといいますと、4つのダイアログをメインダイアログから呼び出すのですが、その4つのダイアログには共通するコントロールがあり、そのコントロールの動作もその位置も全く同じなのです。
そのため、いちいち4つの...続きを読む

Aベストアンサー

私、CEの経験がないので厳密なところはわからないのですが、
一般的なMFCであれば、可能です。
ただし、条件により困難さが変わります

1)4つのダイアログが全て同じコントロールのみからなる場合
  コントロールは同じだが、ラベルのキャプションが違うとか
  リストボックスのデータが違うとかいう場合です。

  非常に単純です。普通の派生と全く同じ感じです
  OnInitDialog等適当な関数をオーバーライドするだけです。

2)共通のコントロール以外に独自のコントロールも持つ場合
  多少困難です
  いくつかアプローチが考えられます。
  a) ダイアログ・テンプレートを個別に持つ方法
    リソース内のダイアログ・テンプレートは(共通のコントロールも含め)
    コピー&ペーストなどで独自に作成します(4つ作ります)
それぞれを制御するクラスですが、
    ウィザードのサポートを受けられない
    (ウィザードではCDialog派生にされてしまう)
    ので、既存のCDialog派生クラスを参照して
    自力で希望のCDialog派生からさらに派生させるようにします

    リソースIDとクラスの結びつけ方法などは既存のクラスを
    参考にしてください

  b)リソースも完全に共通化する
    ちょっと難しいかもしれません。
    OnInitDialog等で自力でコントロールをCreateします。
    レイアウトが視覚的にできないので非常に困難ですが、
    隣接するコントロールの位置情報をもとに計算するなどしてください。

    ダイアログの大きさに余裕があり、
    追加するコントロールも小さなもの
    (1行のみのエディット等)であれば、
    最初から場所をstaticコントロールで場所を確保しておき
    非表示にしておいて、
    派生クラスで、そのstaticの位置を取得するとかなり楽ができます。

    派生クラスで、本格的にレイアウトが変わってしまう場合は、
    レイアウトを頭に入れながら、Createし、試行錯誤で
    完成させることになるでしょう。


以上の方法がCEでも通じるのかわかりませんが、
参考になれば幸いです。    

   

私、CEの経験がないので厳密なところはわからないのですが、
一般的なMFCであれば、可能です。
ただし、条件により困難さが変わります

1)4つのダイアログが全て同じコントロールのみからなる場合
  コントロールは同じだが、ラベルのキャプションが違うとか
  リストボックスのデータが違うとかいう場合です。

  非常に単純です。普通の派生と全く同じ感じです
  OnInitDialog等適当な関数をオーバーライドするだけです。

2)共通のコントロール以外に独自のコントロールも持つ場合
 ...続きを読む

Q迷わないの肯定文

海外の友達から質問されました。

迷わないは、”ない”で終わってるから否定文、
では、肯定文はなんですか?と、聞かれました。

どこかの歌詞からひっぱてきたと言ってます。
本人は覚えてなく、浜崎、モームスが好きなので、そのあたりの歌詞だと思うので、ここでの迷わないはきっと、”私は決めた”の感じだと思います。

”迷う”が肯定文になりますか?

Aベストアンサー

こんにちは。4/4の英語のご質問以来ですね。

「ない」は、話し手が述べている事柄が、否定的なものであることを断定するのに使う助動詞で、動詞の未然形に接続します。文語の打ち消しの「ず」にあたります。

ここでは「迷う」という肯定形の動詞の未然形「迷わ」+否定の助動詞「ない」が接続し、「迷う」という肯定形を否定した形です。おっしゃる通り、肯定文は「迷う」となります。

「迷う」ことを否定し、その否定を断定する意味で、「決めた」と同等の強い決意を表すことになります。

ちなみに、「~がある」「~がない」の「ない」は「ある」の打消しの形容詞となりますから、区別して下さい。

以上ご参考までに。

Q子ダイアログのデータを親ダイアログで取得するには

VC6.0にてMFCでダイアログベースアプリケーションを作成しています。

親ダイアログ(TestDlg.cpp)のメニューを選択すると、子ダイアログ(SetDlg.cpp)が開き、テキストボックスに文字を入力し、ボタン押下によりテキストボックスの入力数字を確定(グローバル変数(igStatu)に代入)しています。
子ウインドウで入力確定したデータを、親ダイアログにて使用したいのですが、データが受け渡されずに、親ダイアログ側にデータが入りません。
どのようにしたら、子ダイアログで設定したデータを親ダイアログで取得することができるのでしょうか?

C++、MFCともに全然わかっていませんがお願いします。

グローバル変数は、TestDlg.cpp、SetDlg.cppがインクルードしているTest.h内にstatic宣言しています。
static宣言しないとリンクエラー2005になってしまいます。

Aベストアンサー

Test.h内で
extern int igStatu;

TestDlg.cpp内で
int igStatu;

とすればいいのでは?
externについて調べてみてください。

参考URL:http://homepage3.nifty.com/mmgames/c_guide/20-02.html

Q迷わない子

優柔不断な子同士だと行き先が決まらなかったりで話がなかなか進まないですよね。
しかし私はどこ行く?となるとすぐに思いつきます。
あまり迷わず直感で思い浮かんだ場所に行こうと考えます。

どこ行くか聞かれてすぐに回答できるので異性同姓問わず毎回私の行きたい場所ばかりです。
30分のお茶も私の思いついた店だし、遊ぶ時も私の行きたい場所。
どこ行くと聞かれて、相手の意見を聞いて悩むようなら自分の意見を述べます。
もちろん私の知る範囲で相手が行きたくなさそうな場所や興味のなさそうな事はさけています。
結果お互い楽しんでますが、すぐに決めれる私は皆さんからみてどうなのでしょうか?
そこが気になるので心では行きたい場所が決まっていても少し悩むふりをして決まらないようなら自分の意見を述べます。

Aベストアンサー

そういう人がいてくれると助かります。
私は決められないほうです。

実際、迷って決められないときって結構心苦しいんですよね。
でも、迷うんです。
で、実は結局どこでも良いんですよ。
どこでもいいから逆に決め手がなくて迷うんです。

例えば、食事なら別に和食でも中華でも洋食でも何でも良いんですね。別に気分で「これが食べたい」というのはありません。
だから、迷うんですね。
「和食?なんで?」って感じで自分の中で考えると答えが出ないんです。

ですから、決めていただけるとすごく楽です。

もちろん、時には自分で行きたいところなんかがある場合もあります。
そう言う場合に先に決められると言えないってこともあります。
でも、それでも良いんですよ。
本当に行きたい時は、それでも言えますよ。
ただ、先に言われて黙る時は、その程度の希望しかもってないだけですから。

Qスレッド処理からダイアログを表示するには?

Windows XPとVC++ 6.0で
時間のかかる大量の計算をするプログラムを作っています。

計算部分はスレッド処理にして
進捗ダイアログ(CDialogにCProgressCtrlを貼り付けたもの)
を表示します。

・CWinAppのInitInstanceで計算処理開始(AfxBeginThread)
・計算処理内で進捗ダイアログをCreate
・計算の進み具合によって進捗ダイアログのプログレスバーを更新

上記の流れではうまくいっていたのですが
以下のように変更したところ、進捗ダイアログをCreateするところで
プログラムが応答なしになってしまうようになりました。

・メインダイアログ(モーダル)
・メインダイアログのAボタンクリックでダイアログAを開く(モーダル)
・ダイアログAの実行ボタンクリックで計算処理開始(AfxBeginThread)
・計算処理内で進捗ダイアログをCreate
・計算の進み具合によって進捗ダイアログのプログレスバーを更新

MFC Wizardでダイアログベースで作成、MFCの共有DLLを使用しています。

モーダルダイアログ→スレッド→CDialog.Createに
制限があったりするのでしょうか。
どうかご教授ください。

Windows XPとVC++ 6.0で
時間のかかる大量の計算をするプログラムを作っています。

計算部分はスレッド処理にして
進捗ダイアログ(CDialogにCProgressCtrlを貼り付けたもの)
を表示します。

・CWinAppのInitInstanceで計算処理開始(AfxBeginThread)
・計算処理内で進捗ダイアログをCreate
・計算の進み具合によって進捗ダイアログのプログレスバーを更新

上記の流れではうまくいっていたのですが
以下のように変更したところ、進捗ダイアログをCreateするところで
プログラムが応答なしになっ...続きを読む

Aベストアンサー

スレッドを作成した側の待機処理ループの中にメッセージポンプを作成してやればよさそうですよ

pThread->ResumeThread();
do {
  AfxGetApp()->PumpMessage();
} while( WaitForSingleObject( pThread->m_hThread, 0 ) != WAIT_OBJECT_0 );
といった具合で …

メインスレッド寝てしまっているので反応無しになるのかも

Q東京駅(新幹線で到着)で迷わない待ち合わせ場所

まだ先の話なのですが、今度、東京駅で両親と待ち合わせをします。しかし、どこで待ち合わせをしたらいいのか困っています。分かりやすい場所をどなたか教えてください。
両親は、関西から新幹線(東海道新幹線)で到着します。両親が東京に来るのは初めてです。もちろん、東京駅も初めて。私は、東京は初めてではありませんが、過去に3回くらいしか行ったことがありません。もちろん東京駅に一人で行くのは初めてですが。(関西で生まれ育ちました)一時帰国中のため(海外在住です)、日本では携帯電話を持っておりません。
こんな私たちが東京駅で待ち合わせをしようとしています。新幹線で到着する両親が改札を出て(改札は複数あるのですか?)、一番分かりやすい場所を待ち合わせ場所にしたいのですが、どこかいい場所がありますか?東京にお住まいの方、助言をお願いします。

Aベストアンサー

駅の構内構外問わずですか?構内は非常に複雑な上、新幹線改札が相当あります。
人も多いです。構外で良いなら2か所お勧めの場所があります。

1.東海道新幹線日本橋口
http://www.narita-airport.jp/jp/guide/service/list/svc_19.html
上述マップの「1階」というPDFファイル見てください。分かりやすくなります。
ここならまず間違えなく会えると思います。JR東海(東海道新幹線)と
JR東日本(東北等々の新幹線)2か所あります。JR東海(東海道新幹線)の方です。
ご両親には、進行方向一番前にある日本橋口の改札を出たところ、
と言えば分かると思います

2.大丸東京店
関西の方なら大丸と聞くだけで、何となく親近感があるのでは?
八重洲口を出たら上を見上げてください。見慣れた大丸のロゴがみえると思います。
1階のインフォメーション横あたりはいかがでしょう。
http://www.daimaru.co.jp/tokyo/floor/1f.html

余計なお世話ですが、トラブルも予想されるので、
成田空港でレンタルの携帯電話借りた方が良くないですか?

参考URL:http://www.narita-airport.jp/jp/guide/service/list/svc_19.html

駅の構内構外問わずですか?構内は非常に複雑な上、新幹線改札が相当あります。
人も多いです。構外で良いなら2か所お勧めの場所があります。

1.東海道新幹線日本橋口
http://www.narita-airport.jp/jp/guide/service/list/svc_19.html
上述マップの「1階」というPDFファイル見てください。分かりやすくなります。
ここならまず間違えなく会えると思います。JR東海(東海道新幹線)と
JR東日本(東北等々の新幹線)2か所あります。JR東海(東海道新幹線)の方です。
ご両親には、進行方向一番前にある日本橋口の改札...続きを読む

QワーカスレッドAfxBeginThreadのスレッド起動を遅延させたい

アラーム情報などをBASP21を用いてE-Mail送信するプログラムを
マルチスレッドにしていました。
自己メールサーバーを立てていた場合は、1秒間に何件でもセッション
張ってもよかったのですが、訳あってOCNのメールサーバーを使うように
したところ、1秒間に複数のセッションを張ると迷惑メール送信
と認識されるため、接続が拒否されていまいます。

そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす
ためにAfxBeginThreadの後に

Sleep( 5* 1000 );

を入れて1秒間に複数送信しないようにしたつもりなんです
が、何故かSleepが効かな状況です。

エラー内容としては、次のように表示されます。
Too Many Session 421
細かく見ていくと、状況によって次のエラーでした。
http://homepage1.nifty.com/yito/anhttpd/winsock_error.html
10060 WSAETIMEDOUT
10061 WSAECONNREFUSED Connection refused

ログを見てもスリープが効いておらず、間隔なしにアラームメールが
1秒間に10件近く送信されてしまいます。


一応渡されたスレッドの最後に
AfxEndThreadを書いてみたり書かないようにしてみたんですが、
状況は変わらずです。

#include "stdafx.h"
#include "windows.h"

for( i=0;i<ALARM_MAX;i++ ){
m_pThreadCL[i] = AfxBeginThread(ThreadProcCL, (LPVOID)i,THREAD_PRIORITY_NORMAL)
Sleep( 5 * 1000); //::Sleep( 5 * 1000 );の間違い?
}
念の為
スレッド起動をしなければいいのですが、単純にはいかなかった
ため、応急処置としてスレッドの起動間隔を遅延させる方法を
どうにかできないものでしょうか。あくまでも応急処置として、
お願いいたします。

アラーム情報などをBASP21を用いてE-Mail送信するプログラムを
マルチスレッドにしていました。
自己メールサーバーを立てていた場合は、1秒間に何件でもセッション
張ってもよかったのですが、訳あってOCNのメールサーバーを使うように
したところ、1秒間に複数のセッションを張ると迷惑メール送信
と認識されるため、接続が拒否されていまいます。

そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす
ためにAfxBeginThreadの後に

Sleep( 5* 1000 );

を入れて1秒間に複数送信...続きを読む

Aベストアンサー

AfxBeginThreadの 引数dwCreateにCREATE_SUSPENDEDを指定してスレッドを作成するようにしてみてはいかがでしょう

その後 ResumeThreadメソッドでスレッド起動
WaitForSingleObjectなどを使ってスレッドが終了する毎に次スレッドのResumeThreadを呼んでみてはいかがでしょう ...

for(i=0; i< ALARM_MAX;i++) {
m_pThread[i] = AfxBeginThread( ThreadProcCL,(LPVOID)i,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
}

for( i=0; i<ALAM_MAX; i++) {
m_pThread[i]->ResumeThread();
while( WaitForSingleObject( m_pThread[i]->m_hThread, 100 )!= WAIT_OBJECT_0) {
Sleep( 5 * 1000 );
}
}

AfxBeginThreadの 引数dwCreateにCREATE_SUSPENDEDを指定してスレッドを作成するようにしてみてはいかがでしょう

その後 ResumeThreadメソッドでスレッド起動
WaitForSingleObjectなどを使ってスレッドが終了する毎に次スレッドのResumeThreadを呼んでみてはいかがでしょう ...

for(i=0; i< ALARM_MAX;i++) {
m_pThread[i] = AfxBeginThread( ThreadProcCL,(LPVOID)i,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
}

for( i=0; i<ALAM_MAX; i++) {
m_pThread[i]->ResumeThread();
while( WaitForS...続きを読む


人気Q&Aランキング