1

制御の問題に関する投稿をたくさん見てきました。ハングしているアプリケーションを呼び出しますが、ほとんどの場合、.NET1.1で実行されているアプリケーションに制限されているようです。代わりに.BeginInvokeを使用する提案も見ましたが、役に立ちませんでした。.BeginInvokeはハングしませんが、デリゲートも呼び出しません。私の主な関心事は、私が何年も問題なく呼び出して使用していることです。私はそれを広範囲に使用する分野で主要なアプリケーションを持っており、この問題がそこで発生するのではないかと心配しています。動作中のコードと失敗したコードを区別できる限り、私は何も変わっていません。私は問題を再現する非常に単純なコードを書きました(すべて4.0 VS2010で):

Public Class Form1

    Private WithEvents sat As TestInvoke
    Private Delegate Sub doTheUpdateDelegate(ByVal message As String)

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles     Button1.Click
        sat = New TestInvoke

        sat.startAThread()

    End Sub

    Public Class TestInvoke

        Public Event UpdateControl()

        Public Sub startAThread()
            Dim t As New Threading.Thread(AddressOf _startAThread)
            Dim trace As String

            trace = "a"
            t.SetApartmentState(Threading.ApartmentState.STA)

            t.Start()
            t.Join()

        End Sub

        Protected Sub _startAThread()
            Try
                For k = 0 To 10
                    System.Threading.Thread.Sleep(1000)
                    k += 1
                    RaiseEvent UpdateControl()
                Next
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End Sub
    End Class

    Private Sub sat_UpdateControl() Handles sat.UpdateControl
        Try
            Call doTheupdate(Now.ToString)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    Private Sub doTheUpdate(ByVal message As String)
        Try
            If Button1.InvokeRequired = True Then
                Dim objParams As Object() = {message}

                'hangs on the following line
                Button1.Invoke(New doTheUpdateDelegate(AddressOf doTheUpdate),     objParams)

            Else
                Button1.Text = message
            End If
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
End Class

私がここで間違ったことを誰かが見ることができれば、私は本当に感謝しています!

4

2 に答える 2

11

Control.Invoke()呼び出しがハングする理由は1つだけです。または、BeginInvoke()呼び出しがターゲットを実行しない、同じことです。これは、プログラムのメインスレッドであるUIスレッドがアイドル状態でなく、他のことを実行しているときに発生します。

「他の何か」が何であるかは、マップ全体にあります。あなたができる最悪のことは、メインスレッドにワーカースレッドが完了するのを待たせることです。Invoke()を使用する場合、これは保証されたデッドロックです。

状態の診断は非常に簡単で、Debug +BreakAllおよびDebug+Windows+Threadsを使用します。メインスレッドをダブルクリックして、[コールスタック]ウィンドウを確認します。スタックトレースの一番上には「ManagedtoNativeTransition」と表示され、その下にはFPushMessageLoop()が表示されます。他に何かが表示された場合は、デッドロックの原因となるコードが見つかりました。

于 2012-10-25T22:44:00.707 に答える
1

を使用Thread.Joinして、他のスレッドが完了するまでUIスレッドを一時停止します。同時に、Control.InvokeUIスレッドに何らかのアクションを実行させるために使用します。UIスレッドは他のスレッドが終了するのを待っているため、これは機能しません。

Thread.Joinアクションが終了するのを待つ場合は、呼び出しを削除するか、UIスレッドでアクションを実行することをお勧めします。

于 2012-10-25T22:44:53.887 に答える