以前あげたC# .NETアプリケーション開発 徹底攻略 Listing2.26への疑問 – SharpLab.というエントリに対して、なちゃさんから、
なちゃ 09-09-23 09:15:19 JST
本来、デリゲートでBeginInvokeした場合は、必ずEndInvokeする必要がありますね。
リソースリークなども発生する危険があります。
※デリゲート以外でもBegin~系は基本的には同じですがEndInvokeさえすれば、きちんと発生した例外がスローされてきます。
けして例外が握りつぶされているのではなく、正しく使っていないために握りつぶされているように見えているだけですね。
ちょっと書籍の記述がまずいと思います。
という指摘がありました。なるほど!指摘の通り、Begin EndパターンなのでEndInvokeを必ず呼び出す必要がありました。恥ずかしながらすっかり失念していました。。というわけでEndInvokeを使うように修正。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
namespace SharpLab.ThreadExceptionTest {
static class Program {
static Form form;
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main() {
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form();
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
MessageBox.Show(e.Exception.Message);
}
static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
Exception ex = (Exception)e.ExceptionObject;
MessageBox.Show(ex.Message);
Application.Exit();
Environment.Exit(0);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace SharpLab.ThreadExceptionTest {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private delegate void SampleDelegate();
private void button1_Click(object sender, EventArgs e) {
SampleDelegate a = new SampleDelegate(ThreadMethod);
a.BeginInvoke((asyncResult) => {
a.EndInvoke(asyncResult);
}, null);
}
private void ThreadMethod() {
//意図的に起こした例外
Thread.Sleep(5000);
throw new Exception("非同期スレッドで起こった例外です。");
}
}
}
こんな感じでしょうか。ちゃんとサブスレッドで例外が発生した時にUnhandledExceptionが呼び出されるようになりました!これで正しく確実な終了処理ができそうです。サブスレッドの処理内容をすべてtry~catchで括って必要に応じて例外をリスローする必要があると憶えていたのですが、そうではなかったのですね。いつもtry~catch書きながらなんかおかしい気がしていたのですが、これですっきりしました。なちゃさん、ありがとうございました。
Related Entries
Trackbacks : 1
- Trackback URL for this entry
- http://blog.sharplab.net/computer/cprograming/3253/trackback/
Listed below are links to weblogs that reference this entry
- ピンバック from C# .NETアプリケーション開発 徹底攻略 Listing2.26への疑問 - SharpLab. 09-09-23 15:51:11 JST
-
[...] きました。こちらもあわせてご参照ください:UnhandledExceptionイベントは、サブスレッドの例外も捕捉可能 – SharpLab. [...]
Webkit.NETのDOMをJavaScriptを使って操作する方法