Control.Invoke是挂(Control.Invoke is hanging)

2019-07-02 16:01发布

我已经看到了关于control.Invoke悬挂应用的问题一吨后,但他们大多似乎仅限于那些在.NET 1.1上运行。 我也见过建议使用.BeginInvoke,而不是我所尝试,但都无济于事。 .BeginInvoke不挂,但它也不会调用委托。 我主要担心的是,我已经使用.Invoke多年,没有问题,我已经在使用它广泛领域的重大应用程序,我很担心这个问题会突然出现在那里。 我什么都不做不同的,据我可以在我的工作代码和失败之间的代码告诉。 我已经写了代码死的简单一点的是复制问题(都在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

如果任何人都可以看到我做了什么错在这里我会很感激!

Answer 1:

这里只有一个原因Control.Invoke()调用将挂起。 或BeginInvoke的()调用不执行它的目标,同样的事情。 它发生在程序的主线程,UI线程,是不是闲置,忙于做其他事情。

什么是“别的东西”可能是各地图。 你能做的最糟糕的事情有主线程等待工作线程来完成。 这是一个保证僵局,如果你使用的invoke()。

该条件是非常容易诊断,使用调试+打破了所有和调试+的Windows +主题。 双击主线程,并期待在调用堆栈窗口。 堆栈跟踪的顶部应该说“托管到本机过渡”,它下面的一个应该是FPushMessageLoop()。 如果你看到别的东西,那么你已经找到了导致死锁的代码。



Answer 2:

您正在使用Thread.Join让UI线程暂停,直到另一个线程完成。 同时使用Control.Invoke让UI线程做一些动作。 因为UI线程正在等待另一个线程来完成这将无法正常工作。

我建议你要么删除Thread.Join通话,或者如果你想让它等待动作完成做UI线程你的行动。



文章来源: Control.Invoke is hanging