C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 17 を表示中)
■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がキャッチされずにフリーズしていたので、
果たして『それで万全なのかが確信できない』というわけです。
必ず例外を投げてくれるのなら(エレガントとは言えませんけど^^;)安心なのですが。

返信 編集キー/


管理者用

- Child Tree -