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

Exceptionキャッチについて

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

本掲示版にはいつもお世話になっております。
今回はExceptionをキャッチすることで、不明な点が
ありましたので質問させていただきます。

Formクラス内で非同期デリゲートを使用して非同期処理(BeginInvoke)
を行ったときに非同期処理で発生したスレッド内(Formのメインスレッドとは別)
で例外が発生した時に、例外が発生したプロシージャ内でExceptionをキャッチ
できるのですが、Throwするとどこにもキャッチされません。

ThreadExceptionやUnhandledExceptionのハンドラを用意しているのですが
キャッチされません。

Formのメインスレッドとは別で発生したスレッドで発生したExceptionをキャッチ
する方法はあるのでしょうか?

申し訳ございませんが、よろしくお願いします。
■No21919に返信(zonoさんの記事)
> ThreadExceptionやUnhandledExceptionのハンドラを用意しているのですが
> キャッチされません。
>

これによると、UnhandledExceptionなんですが、駄目ですか?
Application.ThreadExceptionってのもあるけど
http://www.atmarkit.co.jp/fdotnet/dotnettips/320appexception/appexception.html
■No21920に返信(やじゅさんの記事)
> ■No21919に返信(zonoさんの記事)
>>ThreadExceptionやUnhandledExceptionのハンドラを用意しているのですが
>>キャッチされません。
>>
>
> これによると、UnhandledExceptionなんですが、駄目ですか?
> Application.ThreadExceptionってのもあるけど
> http://www.atmarkit.co.jp/fdotnet/dotnettips/320appexception/appexception.html

状況としては、どこにもキャッチされなかった時、ダイアログ
も表示されず、何事もなかったようになってしまいます。

教えていただいた方法でも駄目でした・・・

非同期デリゲートを使用するところに問題があるのでしょうか?
■No21921に返信(zonoさんの記事)
> ■No21920に返信(やじゅさんの記事)
>>■No21919に返信(zonoさんの記事)
> >>ThreadExceptionやUnhandledExceptionのハンドラを用意しているのですが
> >>キャッチされません。
> >>
>>
>>これによると、UnhandledExceptionなんですが、駄目ですか?
>>Application.ThreadExceptionってのもあるけど
>>http://www.atmarkit.co.jp/fdotnet/dotnettips/320appexception/appexception.html
>
> 状況としては、どこにもキャッチされなかった時、ダイアログ
> も表示されず、何事もなかったようになってしまいます。
>
> 教えていただいた方法でも駄目でした・・・
>
> 非同期デリゲートを使用するところに問題があるのでしょうか?

サンプルソースを記述した方がよいと思いましたので記述します

ex)formを起動後、ボタンを押下した後に自作したクラスのオブジェクトを生成
 し、メソッドをコール。メソッド先では、BeginInvokeを行い非同期処理を行う。
 非同期処理の中でExceptionを発生させたときに、Catch文の中でThrowしているが
 Formは例外をキャッチしない。(ダイアログも表示されない)

【form】※Windows フォーム デザイナで生成されたコードは記述を省略
Public Class Form1
Inherits System.Windows.Forms.Form
<STAThread()> _
Shared Sub Main()
' ThreadExceptionイベント・ハンドラを登録する
AddHandler Application.ThreadException, AddressOf Application_ThreadException

' UnhandledExceptionイベント・ハンドラを登録する
AddHandler Thread.GetDomain().UnhandledException, AddressOf Application_UnhandledException
Application.Run(New Form1)
End Sub

' 未処理例外をキャッチするイベント・ハンドラ
' (Windowsアプリケーション用)
Public Shared Sub Application_ThreadException(ByVal sender As Object, ByVal e As ThreadExceptionEventArgs)
MsgBox("Application.ThreadException")
End Sub

' 未処理例外をキャッチするイベント・ハンドラ
Public Shared Sub Application_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
MsgBox("Application.UnhandledException")
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try

Dim te As New Test
te.test()
Catch ex As Exception
Throw ex
End Try
End Sub
End Class


【自作クラス】
Public Class Test

Private Delegate Sub dgtest()

Public Sub test()
Try
'Dim i(0) As Integer
'i(10) = 0

Dim dg As dgtest
dg = New dgtest(AddressOf Me.hidouki)

dg.BeginInvoke(Nothing, Nothing)

Catch ex As Exception
Throw ex
End Try
End Sub


Public Sub hidouki()
Try
Dim i(0) As Integer

i(10) = 1

Catch ex As Exception
Throw ex
End Try
End Sub
End Class

もし対応策がありましたらよろしくお願いいたします。
> Formのメインスレッドとは別で発生したスレッドで発生したExceptionをキャッチ
> する方法はあるのでしょうか?

これは、UnhandledExceptionで可能です。ただ、BeginInvokeで呼び出した先での例外は、EndInvokeを呼び出さないと捕捉できないのではないでしょうか。

捕捉されなかった例外がスローされたことを知る
http://dobon.net/vb/dotnet/programing/unhandledexception.html
■No21923に返信(管理人さんの記事)
>>Formのメインスレッドとは別で発生したスレッドで発生したExceptionをキャッチ
>>する方法はあるのでしょうか?
>
> これは、UnhandledExceptionで可能です。ただ、BeginInvokeで呼び出した先での例外は、EndInvokeを呼び出さないと捕捉できないのではないでしょうか。
>
> 捕捉されなかった例外がスローされたことを知る
> http://dobon.net/vb/dotnet/programing/unhandledexception.html
>

EndInvokeを呼び出すということは、BeginInvokeを呼び出したスレッドが
待ち合わせ(ブロック)を行うということですよね??
そうなると非同期処理が実現できないように思えてしまいます。

待ち合わせを行わずスレッドの完了を知ることはできないですよね??
> 待ち合わせを行わずスレッドの完了を知ることはできないですよね??

とりあえず、

http://codezine.jp/a/article.aspx?aid=139&p=2#delegate

をご覧ください。

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