- - PR -
別スレッドで発生した例外の捕捉について
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2007-06-28 16:12
お世話になっております。
VB.NETでソケット通信プログラムを作成しております。 クライアント⇒サーバの接続確立時に、それを監視するための スレッドを生成し、一定時間経過した場合にExceptionをスローする。 という処理を取り入れようとしています。 ここで、別スレッドでExceptionをスローした場合、 その例外をスレッド呼び出し元で捕捉できずに困っております。 どなたか解決方法を教えていただけないでしょうか? 現在のコードは下記のような状態です。 '接続監視用スレッド Private Sub WatchConnect() System.Threading.Thread.Sleep(My.Settings.Timeout) Throw New TimeOutException("通信タイムアウトのため例外を発生させます") End Sub 'サーバとの通信を開始 Friend Sub StartCommunicate() logger.Debug("start:StartCommunicate") 'サーバーのホスト名とポート番号 Dim host As String = My.Settings.hostIPAddress Dim port As Integer = My.Settings.port Dim RETRY_CNT As Integer = My.Settings.retryCount Dim retryCnt As Integer = 0 While True '接続監視用に別スレッドを生成し、サーバとの接続処理を監視する Dim watchThread As New Thread(New ThreadStart(AddressOf WatchConnect)) Try watchThread.Start() 'TcpClientを作成し、サーバーと接続する Dim client As New TcpClient(host, port) 'NetworkStreamを取得する networkStream = client.GetStream() binaryWriter = New BinaryWriter(networkStream) binaryReader = New BinaryReader(networkStream) Exit While Catch ex As TimeOutException logger.Error(ex) If retryCnt = RETRY_CNT Then Throw ex End If retryCnt = retryCnt + 1 client = Nothing Catch ex As Exception logger.Error(ex) If retryCnt = RETRY_CNT Then Throw ex End If retryCnt = retryCnt + 1 client = Nothing System.Threading.Thread.Sleep(My.Settings.retryInterval) Finally watchThread.Abort() End Try End While logger.Debug("end:StartCommunicate") End Sub 以上、よろしくお願いいたします。 |
|
投稿日時: 2007-06-28 16:18
すいません。コードのインデントが設定されていないので、
非常にみにくいですね。もう一度書き込みさせてください。 '接続監視用スレッド Private Sub WatchConnect() System.Threading.Thread.Sleep(My.Settings.Timeout) Throw New TimeOutException("通信タイムアウトのため例外を発生させます") End Sub 'サーバとの通信を開始 Friend Sub StartCommunicate() logger.Debug("start:StartCommunicate") 'サーバーのホスト名とポート番号 Dim host As String = My.Settings.hostIPAddress Dim port As Integer = My.Settings.port Dim RETRY_CNT As Integer = My.Settings.retryCount Dim retryCnt As Integer = 0 While True '接続監視用に別スレッドを生成し、サーバとの接続処理を監視する Dim watchThread As New Thread(New ThreadStart(AddressOf WatchConnect)) Try watchThread.Start() 'TcpClientを作成し、サーバーと接続する Dim client As New TcpClient(host, port) 'NetworkStreamを取得する networkStream = client.GetStream() binaryWriter = New BinaryWriter(networkStream) binaryReader = New BinaryReader(networkStream) Exit While Catch ex As TimeOutException logger.Error(ex) If retryCnt = RETRY_CNT Then Throw ex End If retryCnt = retryCnt + 1 client = Nothing Catch ex As Exception logger.Error(ex) If retryCnt = RETRY_CNT Then Throw ex End If retryCnt = retryCnt + 1 client = Nothing System.Threading.Thread.Sleep(My.Settings.retryInterval) Finally watchThread.Abort() End Try End While logger.Debug("end:StartCommunicate") End Sub |
|
投稿日時: 2007-06-28 16:31
コードを入力するときは、BBコードを使うといいです。
[code] [/code] というようなタグで囲むとインデントも正しくやってくれますよ(これは全角で 書いてますが、実際は半角で入力します)。 で、別スレッドで発生した Exception ですが、基本的には取れないと思 います。 別スレッドで発生した Exception を自スレッドで取得することは不可能だ と思うので、やるとしたら別スレッド内でキャッチした Exception を Invoke で渡してもらう(受け取った Exception を Exception 型のオブ ジェクトとして扱う)とか、Application.ThreadException イベントを定 義してキャッチするような感じになると思います。 _________________ ぽぴ王子@わんくま同盟 ぽぴ王子の人生プログラミング中 / ぽぴンち。 |
|
投稿日時: 2007-06-28 20:34
ごめんなさい、コードからしたいことが読み取れませんでした。
WatchConnect は、不要だと思います。Timmer で十分ではないでしょうか。 いや、スレッドをわける必要があるとお考えの場合、あなたが考えている処理を、日本語で説明してください。 今の実装では、指定時間後に例外が発生するというだけです。タイマーでイベントを発生させ、フラグを立てれば十分だと思います。 _________________ |
|
投稿日時: 2007-06-28 20:38
Jittaさん、回答ありがとうございます。
>WatchConnect は、不要だと思います。Timmer で十分ではないでしょうか。 >いや、スレッドをわける必要があるとお考えの場合、あなたが考えている処理を、日>本語で説明してください。 >今の実装では、指定時間後に例外が発生するというだけです。タイマーでイベントを>発生させ、フラグを立てれば十分だと思います。 申し訳ありません。別スレッドからの例外をメインスレッドで捕捉できると 思い込んでいました。。。 タイマーを用いた接続監視方法の 具体的なコーディング例を教えていただけないでしょうか? |
|
投稿日時: 2007-06-29 07:45
具体的なコードは、MSDNに例示されていると思いますが、探してみましたか?探す手間くらいは、惜しまずかけて欲しいです。
それで見つからなければ、どの検索エンジンで、どの様なキーワードで検索したか、教えてください。 また、仕様が分からなければ、コードを書くことも難しいです。 今携帯からなので、コード例をあげるとなると、夜まで待っていただくことになります。それより、自分で探す方が早いと思いますよ。 |
|
投稿日時: 2008-03-01 17:47
見たところASP.NETでの実装ではなさそうなので、どうしても別スレッドの例外を補足するような事がしたい場合はBackGroundWorkerを使えばよいと思います。
.net2.0以上限定になりますが。 BackGroundWorkerでは、RunWorkerCompletedイベントがメインスレッドで発生します。 ですので DoWorkイベントのイベントハンドラで監視メソッドをループさせます。 例外を投げたい状態に移行したら、ループを終了させRunWorkerCompletedイベントのイベントハンドラで例外を投げます。 厳密には別スレッドの例外の補足ではないですが、同じようなことが実現できると思います。 未熟なので少し恥ずかしいですが、自サイトにサンプルコードをC#でおいておきました。 よければ読んで見てください。 |
1