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

イベント内での例外のCatchはどこ?

環境/言語:[Windows2000 VB.NET]
分類:[.NET]

Private Sub aaa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles aaa.Click
Try
処理A
Catch ex As Exception
Throw ex
End Try

End Sub

の時はこのフォームのインスタンスを作成したところまで例外が戻って来たのですが、

Private Sub bbb_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles bbb.KeyDown

If e.KeyCode = Windows.Forms.Keys.F4 Then
Try
処理A
Catch ex As Exception
Throw ex
End Try
End If
End sub

とやると、どこにもCatchされないようなんです。

どうすればキャッチできるのでしょうか?よろしくお願いします。
> Private Sub bbb_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles bbb.KeyDown
>
> If e.KeyCode = Windows.Forms.Keys.F4 Then
> Try
> 処理A
> Catch ex As Exception
> Throw ex
> End Try
> End If
> End sub
>
> とやると、どこにもCatchされないようなんです。
>
> どうすればキャッチできるのでしょうか?よろしくお願いします。

こんにちわ。

tryの外にif分があるからじゃないでしょうか?
Try
If e.KeyCode = Windows.Forms.Keys.F4 Then
処理A
End If
Catch ex As Exception
Throw ex
End Try

こうすればいいと思います。
はじめまして、ゆかりです。

わたしもC#で同じようなことがありましたが、
コントロールで発生したイベントは、そのイベント発生時に一個のスレッドが
出来上がるみたいです。

だから、コントロールごとに別のスレッドが動いていることになって、例外はほかのスレッドまでは、throwされないみたいですよ(この辺が良くわかってないです、ごめんなさい)。

多分、VB.NETでも同じだと思います。
例外の処理自体は難しくなるものの、Application.ThreadExceptionイベントで例外の発生を実質catchすることができるようです。
お返事ありがとうございます。

>SHさん
if文の外に書いてみても結果は同じでした。

>ゆかりさん、Codingslaveさん
なるほど。そういう動きをするんですね。
時間あるときにちょっと試してみます。
平和的に終わろうとしているところを申し訳ないのですが、私にはよく分からない点が多々あります。(私だけ勘違いしていたら本当に申し訳ないのですが。)

イベントハンドラが別のスレッドで実行されるという結論に落ち着いている感じですが、私には?です。そもそもClickイベントハンドラではうまく行って、KeyDownイベントハンドラでは失敗する理由が分かりません。

また、Clickイベントハンドラ内でスローされた例外がフォームのインスタンスを作成したところで捕捉できたとありますが、そのようなことはありえるでしょうか?コンストラクタでスローされた例外なら捕捉できるとは思いますが...。

mmmさんが例外をキャッチするところでどのようなコードを書いているか分かりませんが、私のところでは、少なくとも次のような感じではうまく行きました。ここではForm1とForm2があり、Form1にはButton1が、Form2にはButton1とTextBox1があるものとします。Form1のButton1をクリックすると、Form2が表示されます。

Form2のコードは次のような感じです。(例外をスローするだけ。)

Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Windows フォーム デザイナで生成されたコード "
(省略)
#End Region

Private Sub TextBox1_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles TextBox1.KeyDown
Throw New Exception("ERR")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Throw New Exception("ERR")
End Sub
End Class

問題はForm1です。Form1のButton1のClickイベントハンドラを次のようにすると、例外は捕捉できません。(当たり前ですが。)

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim f As Form2
Try
f = New Form2
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
f.Show()
End Sub

次のようにすると、捕捉できます。

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim f As Form2
f = New Form2
Try
f.ShowDialog()
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
f.Dispose()
End Try
End Sub

mmmさんはどのように書いたのでしょう。

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