■6822 / ) |
Re[9]: 別スレッドでShowDialogしたフォームのクローズ |
□投稿者/ 困ったちゃん (7回)-(2007/08/24(Fri) 12:18:47)
|
■No6802 (れい さん) に返信
詳細なアドバイス、ありがとうございます。
> Undocumentedだと思います。
そうですか。残念です。
> Closingにフラグ組み込むだけではだめです。
> Form.CloseされてからClosingに入る前にInvokeされたら止まります。
そうなんです。原コード■No6760 のForm2を;
'/*** Form2 (経過表示用フォーム) ***/
Public Class Form2 : Inherits System.Windows.Forms.Form
'// Friend WithEvents RichTextBox1 As System.Windows.Forms.RichTextBox
Private Delegate Sub WriteLineDelegate(ByVal text As String)
Private dlgt As New WriteLineDelegate(AddressOf Me.WriteLine)
Private blockedInvoking As Boolean '// Closingイベントフラグ
'// リッチテキストボックスに文字を追記表示する
Public Sub WriteLine(ByVal text As String)
If Me.IsDisposed OrElse Not Me.IsHandleCreated Then Return
If Me.InvokeRequired Then
If blockedInvoking Then Return ' // Closing中ならばInvokeを阻止
Try
Me.Invoke(dlgt, New Object() {text})
Catch ex As System.ObjectDisposedException '// 破棄後のアクセスは無視
End Try
Else
With Me.RichTextBox1
.AppendText(text & vbCrLf)
.ScrollToCaret()
.Focus()
End With
End If
End Sub
'// フォームを閉じようとしたときにフラグを立てる
Private Sub Form2_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
blockedInvoking = True
' // 以下は『確認のためのコード』
Me.WriteLine("blockedInvoking = True")
Static Dim retry As Boolean
If Not retry Then e.Cancel = True ' // 1回目のClosingのみキャンセル
retry = True
End Sub
End Class
と書き換えて、書き込み中にクローズボタンを押して表示を止めてみると、
1巡目です。
...
163巡目です。
164巡目です。
blockedInvoking = True
165巡目です。
(停止)
のようになって、フラグを立てた後でも1回Invokeに進んでしまうことが判ります。
で、改めて『確認のためのコード』以下を外すと、最後のInvokeがObjectDisposedException
をスローするので、Catch句で殺しています。(原コードではForm1側に記述していました)
百回程度試行してみましたが、上記のコードだとフリーズすることはありませんでした。
しかし原コードでも、ObjectDisposedExceptionがキャッチされずにフリーズしていたので、
果たして『それで万全なのかが確信できない』というわけです。
必ず例外を投げてくれるのなら(エレガントとは言えませんけど^^;)安心なのですが。
|
|