DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Process.Exitedイベントのタイムラグ

環境/言語:[OS : Windows XP Professional / 言語 : C# / .NET Framework : 2.0]
分類:[.NET]

【解決したい問題】

A.exeからB.exeをprocess.startで起動しています。(A.exeもB.exeも自作)さらにB.exeの終了を監視するために、Exitedイベントを使用しています。B.exe起動中にA.exeから別のexeも起動する可能性があるため、WaitForExitは使用していません。

監視というのはA.exeから起動しているexeがすべて終了してない限り、A.exeを終了できなくしています。(メッセージを表示してClosingをキャンセルしてます)

しかし、B.exeをApplication.Exitで終了してから、A.exe内のExitedイベントが発生するまでに約2秒ほどのタイムラグが発生しています。
このタイムラグのせいでB.exeを閉じて連続してA.exeを閉じようとしても「まだB.exeが終わってない」と言われるというような状態になっています。

このタイムラグを解消する方法、または別の手法をご存知の方はいらっしゃらないでしょうか?

【解決するために何をしたか】
ネットで検索してもWaitForExitを使用するパターンばかりで、Exitedイベントの情報があまり見つかりませんでした。
実際にプロセスが終了してないんじゃないですか?
Application.Exit はメッセージループ終了をフレームワークに通知するだけで、即座にプロセスを終了させるものじゃありません。
// プロセスを終了させるメソッドがあるとして、それも OS に対してプロセス終了を要求するだけであって OS による後片付けによっていくらか遅延する可能性はあるでしょう。
取りあえず、タスクマネージャでB.exeがいつ完了するか眺めてみればいかがでしょう。
> 取りあえず、タスクマネージャでB.exeがいつ完了するか眺めてみればいかがでしょう。

確かに、B.exeの画面は見えなくなっても、タスクマネージャには2秒ぐらい残ってますね。

> 実際にプロセスが終了してないんじゃないですか?
> Application.Exit はメッセージループ終了をフレームワークに通知するだけで、即座にプロセスを終了させるものじゃありません。
> // プロセスを終了させるメソッドがあるとして、それも OS に対してプロセス終了を要求するだけであって OS による後片付けによっていくらか遅延する可能性はあるでしょう。

もちろんそうだろうとは踏んでました。
しかしオペレーターに「プロセスが…」と言っても納得いかないでしょうし。画面は見えなくなってますから。
しかも必ず遅延するんですよ。これが「ときどき」とか「機種固有」とかであれば良いのですが、まったく違う機種でも同じ現象が出るんですね。

Program.csのMainの最後の時刻と、呼び出し側のExitedイベントが発生した時刻の間が2秒ぐらいなので、コーディング的に画面を閉じた後に何か処理をやってるわけではないんですね。

しかし、早くプロセスが消えてくれるexeもあるんですよ。目に見えて違うのは画面の大きさ(小さいと早く消える?)ぐらいです。

なので
「こういう組み方をするとプロセスが消えるまでに時間がかかるよ」や
「こういう工夫でプロセスの消え方を早めることができるよ」
というような情報があればと思ったのですが…
> しかし、早くプロセスが消えてくれるexeもあるんですよ。目に見えて違うのは画面の大きさ(小さいと早く消える?)ぐらいです。

何もしないEXEを作ってそれの終了にかかる時間とB.exeの終了にかかる時間を比較してみては?
そこに明らかな差があるなら、その差を追求しましょう。
そこに明らかな差がないなら、それが最短の終了時間だということでしょう。

早くプロセスが消えるexeということですが、これは同じ開発環境(C#、.NET Framework2.0)で作ったものですか?
>■No22585に返信(うにさんの記事)
>
>A.exeからB.exeをprocess.startで起動しています。(A.exeもB.exeも自作)
>

自作なら、マネージドアプリですよね。
プロセス起動にこだわらないならば、
LoadFromメソッドに変更するってのもありかも。
LoadFromなら、A.exeのみがプロセスとなります。
http://park5.wakwak.com/~weblab/mailMagazine/mag029.html
> 早くプロセスが消えるexeということですが、これは同じ開発環境(C#、.NET Framework2.0)で作ったものですか?

はい。同じ開発環境です。

>>しかし、早くプロセスが消えてくれるexeもあるんですよ。目に見えて違うのは画面の大きさ(小さいと早く消える?)ぐらいです。
>
> 何もしないEXEを作ってそれの終了にかかる時間とB.exeの終了にかかる時間を比較してみては?
> そこに明らかな差があるなら、その差を追求しましょう。

はい。現在追求中です。
もしかしたらコントロールの数に比例してるのかもです。
継続して追求してみます。
> 自作なら、マネージドアプリですよね。
> プロセス起動にこだわらないならば、
> LoadFromメソッドに変更するってのもありかも。
> LoadFromなら、A.exeのみがプロセスとなります。

LoadFromメソッドは初めて知りました(勉強不足でした)。
確かに試してみる価値はありそうです。
ただすでに完成しつつあるシステム全体に影響がありそうなので、置き換えが可能かどうかも検討してみます。
> しかしオペレーターに「プロセスが…」と言っても納得いかないでしょうし。画面は見えなくなってますから。

ということであれば、Win32 APIの EnumWindows()を使ってウィンドウ監視するのはどうでしょうか? 対象アプリのウィンドウが見える・見えないで判断すれば、オペレーターさんも混乱しないと思います。

#実際にコード書いて確認してないので外してたらごめんなさい

DOBON.NET | プログラミング道 | プログラミング掲示板