プロジェクトにはプロセスを作成するオブジェクトがあります。このオブジェクトのDispose関数は、プロセスを強制終了します(または試みます)。ただし、プログラムがクラッシュした場合、プロセスは実行されたままになり、クリーンアップされません。これは、プロセスを再度起動しようとしたためにプログラムが次回失敗する原因となり、ロックを取得できません。終了時にプロセスを終了する
このプロセスが強制終了されるようにするにはどうすればよいですか?私はいつも、私はC#と.NET 3.5
プロジェクトにはプロセスを作成するオブジェクトがあります。このオブジェクトのDispose関数は、プロセスを強制終了します(または試みます)。ただし、プログラムがクラッシュした場合、プロセスは実行されたままになり、クリーンアップされません。これは、プロセスを再度起動しようとしたためにプログラムが次回失敗する原因となり、ロックを取得できません。終了時にプロセスを終了する
このプロセスが強制終了されるようにするにはどうすればよいですか?私はいつも、私はC#と.NET 3.5
は、プログラムのどのような立ち上げているを使用しています参考のためusing
ブロック
でプロセスを作成するオブジェクトを使用できますか?最初のインスタンスがまだ実行中であっても、2番目のインスタンスを起動することは可能です。プロセスを起動すると何もロックされません(プログラム自体が変わっていない限り)。
オブジェクトはどのようにプロセスを起動しますか?それにハンドルがある場合は、TerminateProcess APIを呼び出すことで即座に終了することができます。
発信者が死んでも、生成されたプロセスが確実に終了する問題を解決するための、本当にハックリな解決策があります。DebugActiveProcessを呼び出し、子プロセスIDを渡します。
using(Foo bar = new Foo())
{
// ..
}
Foo bar = new Foo();
try
{
bar.DoSomething();
}
catch // if required
{
}
finally
{
if(bar != null)
{
bar.Dispose(); // code from finally clause is ~always executed
}
}
。クラッシュのさまざまなレベルがあります。たとえば、何かがあなたのプロセスを積極的に殺した場合、Dispose/finalizerなどを実行する機会はほとんどありませんが、スレッドが正常に巻き戻されても例外はありますが、 using
を使用しているため)。セットアップの内容を明確にすることはできますか?
親プロセスまたは子プロセスのいずれかが死んだ場合、適切な処置を取ることができるように、双方向プロセス監視が本当に必要です。これを行う最も簡単な方法は、タイマー(30秒ごとに、あなたのニーズに合わせて調整する必要があります)でお互いをpingすることです。次のpingを送信するまでに応答がない場合は、プロセスが死んでしまった、ロックされている、そうでなければ素敵な再生を停止しました。
親が応答を停止した場合、子はただ終了する必要があります。子供が反応しなくなったら、それを殺して新しいものを始める。
どのようにpingを実装するかは、読者の練習として残されていますが、ウィンドウメッセージ、RPC呼び出し、パイプなど、IPCの仕組みによって決まります。単純にする;私はあなたが使用できるものを持っていると確信しています。
私はこれが私に叫ばれるのを知っていますが、Enviroment.Exit()についてはどうでしょうか。それはすべてを殺すはずです=)毎回上記のオプションを実行する方が良いです。また
:あなたのProgram.csで
、あなたはApplication.Run(フォーム)を呼び出す前に、次の操作を行います。
AppDomain.CurrentDomain。UnhandledException + =新しいUnhandledExceptionEventHandler(CurrentDomain_UnhandledException);このようなものであるハンドラに入れ、その後
と:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
String CurrentThreadName = System.Threading.Thread.CurrentThread.Name;
if (e.IsTerminating)
Logger.Log("Program", 0, String.Format("Received fatal unhandled exception on '{0}' thread. Exception will follow.", CurrentThreadName), MsgCategory.Critical, 50);
else
Logger.Log("Program", 0, String.Format("Received unhandled exception on '{0}' thread. Exception will follow.", CurrentThreadName), MsgCategory.Error, 25);
if (e.ExceptionObject != null)
Logger.LogException("Program", String.Format("Unhandled System Exception on '{0}' thread.", CurrentThreadName), 50, (Exception)e.ExceptionObject);
}
catch
{
}
if (e.IsTerminating)
{
Exception ThisException = (Exception)e.ExceptionObject;
String CurrentThreadName = System.Threading.Thread.CurrentThread.Name;
MessageBox.Show(
String.Format(Localization.GetString("fatal_error"), ThisException.GetType().ToString(), ThisException.Message, ThisException.StackTrace, CurrentThreadName)
, Localization.GetString("dialogtitle")
, MessageBoxButtons.OK
, MessageBoxIcon.Error
, MessageBoxDefaultButton.Button1);
}
}
終了コードが実行されないように、プロセスは十分にひどくクラッシュする可能性があります。 このようなメッセージボックスをスローすることは、必ずしも最適なオプションではありません。ユーザーの操作が必要となり、自動再起動ができなくなります。私は主にデバッグビルドでそれを行い、リリース時にオペレータに警告を発します。 –
メッセージボックスは、顧客(またはQAエージェントが最も一般的)が開発チームにリレーできるものを提供することです。また、ログダンプなどを行う場所になる可能性もあります。高稼働時間の製品では、非常にうまく機能しています。 =) – JasonRShaver
あなたは子プロセスの終了を確認したい場合は、独立したシンプルなウォッチドッグ・プロセスを作成することを検討しては、どちらか一方の終了のためのプロセス空間を見て。防弾にする方が簡単です。 すべての状況でクリーンアップコードの実行を保証する方法はありません。
ただし、親プロセスと子プロセスを認識するようにウォッチドッグを設計する方法に関する適切なアドバイスを許可するために、子プロセスの作成方法に関する十分なコンテキストを実際に提供するわけではありません。
これは、「使用する」(元の質問を参照)とほぼ同じです。そして、それは「常に実行されている」というわけではありません。スレッド終了、スタックオーバーフロー、OOM、プロセス終了、「プラグを壁から引き抜く」などの端末が多いことがあります。 –
こんにちはマーク。はい、私は知られています、そして、あなたは絶対に正しい、常にではありません。しかし、通常のアプリケーションライフサイクルのほとんどのケースでは、私は思っています。何も壁のプラグインから助けることができませんでした:)私のコードは、例外の結果としてアプリケーションの終了からすることができました – abatishchev
しかし、私のポイントは:彼らは "使用"ブロックを使用してOPの状態です。つまり、上記のコードは不要です...同じことを達成するために、より多くのキーストロークを使用しました。 –