VS2005 で実行されているプログラムと、実行可能ファイルを直接実行しているプログラムとの間に奇妙な違いがありました。基本的に、Application.DoEvents()
呼び出し内のメソッドで例外がスローされた場合、Visual Studio 内で実行しているときに例外をキャッチできます。コンパイルされた実行可能ファイルを実行すると、例外がキャッチされず、プログラムがクラッシュします。
問題を示す簡単なコードを次に示します。標準の winforms ボイラープレートと 2 つのボタンとラベルを想定します。
これを実行するには、開始ボタンをクリックして 10 秒のカウントを開始します。10 秒が経過する前に、中止ボタンを押します。の内部で例外がスローされますDoEvents()
。例外をキャッチする必要があります。これは、Visual Studio 内で実行している場合にのみ発生します。
private void StartButton_Click(object sender, EventArgs e) {
DateTime start = DateTime.Now;
try {
while (DateTime.Now - start < new TimeSpan(0, 0, 10)) {
this.StatusLabel.Text = DateTime.Now.ToLongTimeString();
Application.DoEvents();
}
MessageBox.Show("Completed with no interuption.");
} catch (Exception) {
MessageBox.Show("User aborted.");
}
}
private void ButtonAbort_Click(object sender, EventArgs e) {
throw new Exception("aborted");
}
これらの例外をキャッチできるようにしたい。それを機能させる方法はありますか?
アップデート:
re-entrant-headache-inducing 以外のアプローチも検討したいと思いDoEvents()
ます。しかし、私はよりうまく機能すると思われるものを見つけていません。私のシナリオは、いくつかの科学機器を制御している長時間実行ループがあり、温度が安定するなどを頻繁に待たなければならないというものです。ユーザーがプロセスを中止できるようにしたいので、プロセスが最初に開始されたサイトでキャッチするカスタム例外を単にスローする中止ボタンを用意しました。それは完璧な解決策のように思えました。何らかの理由で機能しないという事実を除いて。
これを機能させることができない場合、より良いアプローチはありますか?
更新 2:
これを Main() の最初の行として追加すると、実行可能ファイルとして機能しますが、VS では機能しないため、状況が逆になります。クレイジーなことは、ノーオペレーションのように見えることです。これがどのように機能するか理解できます。
Application.ThreadException += delegate(
object sender,
System.Threading.ThreadExceptionEventArgs e
)
{ throw e.Exception; };
これは非常識です。