Control.Invoke悬挂 [英] Control.Invoke is hanging

查看:141
本文介绍了Control.Invoke悬挂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了关于control.Invoke的问题悬应用一吨后,但他们大多似乎仅限于那些在.NET 1.1上运行。我也看到建议使用.BeginInvoke代替,我都试过,但无济于事。 .BeginInvoke不挂,但它也不会调用委托。我最关心的是,我已经使用.Invoke多年,没有问题,我已经在使用它广泛领域的重大应用程序,我很担心这个问题会突然出现在那里。我无所事事不同,据我可以与我的工作code和code失败告诉。我已经写了的code一死的简单一点,复制的问题(都在4.0 VS2010):

I've seen a ton of post regarding the problem of control.Invoke hanging applications but they mostly seemed to be restricted to those running on .NET 1.1. I've also seen suggestions to use .BeginInvoke instead which I have tried but to no avail. .BeginInvoke doesn't hang but it also doesn't call the delegate. My main concern is that I have used .Invoke for years with no issues and I have a major application in the field that uses it extensively and I'm worried that this problem will crop up there. I am doing nothing differently as far as I can tell between my working code and the code that fails. I've written up a dead simple bit of code that replicates the issue (all in 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

如果任何人都可以看到我做了什么错在这里我真的AP preciate了!

If anyone can see what I've done wrong here I'd really appreciate it!

推荐答案

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

There's only one reason a Control.Invoke() call would hang. Or a BeginInvoke() call not executing its target, same thing. It happens when the main thread of the program, the UI thread, is not idle and busy doing something else.

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

What the "something else" could be is all over the map. The worst thing you could do have the main thread for the worker thread to complete. That's a guaranteed deadlock if you use Invoke().

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

The condition is very easy to diagnose, use Debug + Break All and Debug + Windows + Threads. Double-click the Main thread and look at the Call Stack window. The top of the stack trace should say "Managed to Native Transition", the one below it should be FPushMessageLoop(). If you see something else then you've found the code that causes the deadlock.

这篇关于Control.Invoke悬挂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆