2011-02-25 274 views
7

我在显示一个动画,而我的控件正在加载数据。当线程结束时,我隐藏动画并显示控件。有时Control.Invoke()挂起应用程序

protected void InvokeEnableBackControl() 
{ 
    if (this.InvokeRequired) 
    {     
     this.Invoke(new OpHandler(EnableBackControl)); 
    } 
    else 
    { 
     EnableBackControl(); 
    } 
} 

,当我执行这个代码,主线程被下面的代码忌用:所以我从一个线程执行这段代码

protected virtual void EnableBackControl() 
{ 
    if (overlayAnimation.TargetControl != null) 
    { 
     overlayAnimation.TargetControl.BringToFront(); 
    } 

    overlayAnimation.SendToBack(); 
    overlayAnimation.Enabled = false; 
    overlayAnimation.Visible = false;      

}

我米不知道是否被吊死设置EnableVisible属性。你知道任何情况下,可能会从Control.Invoke调用这些属性的应用程序吗?

+0

有没有一个可识别的模式时,它挂起次? – 2011-02-25 15:50:08

+0

@不,只有“有时”。烦人。 – 2011-02-25 16:15:29

+0

记录它挂起的* exact *语句,发布堆栈跟踪。 – 2011-02-25 18:01:44

回答

3

在调试中运行,使应用程序挂起,然后在Visual Studio中暂停调试并检查线程。

+0

这是什么答案?我使用调试器附加了进程,我暂停并检查了线程。这就是我知道线程在第一个代码块中,而主线程在第二个代码块中的原因。 – 2011-02-25 16:17:08

+0

@DanielPeñalba这是一种帮助我的解决方案。因为当你这样做时,你可以看到线程挂起的确切线条。 – Andrey 2011-02-25 16:24:43

+0

我做到了。当我中断所有线程时突出显示的行是'overlayAnimation.Visible = false;'但通常Visual Studio(几乎是2003)停在前一行。有时候,这就是我不确定这条线或上一条线的原因。 – 2011-02-25 16:44:30

7

我,当我执行.Invoke在后台线程,而我的主线程仍然忙于之前碰到的问题 - 这给人的印象是应用程序挂起,因为调用只是坐在那里,等待主线程回应它的注意。可能的原因:

  • 你的主线程被阻塞,在等待着什么
  • 你的主要形式,目前有一个模式对话框了,所以它不是听新的要求
  • 你的主线程在旋转,要么不断地检查,如果有些事情已经完成或正在做新的工作在我的情况下,主线程花了第一分钟在紧密循环中旋转后台线程,所以它没有监听来自后台线程的任何调用请求。

当你连接调试器时,要特别注意你的主控制MessagePump线程正在做什么 - 我怀疑它的缺乏是你麻烦的原因。如果您发现主线程中的回路没有响应,请尝试在回路中插入一个.DoEvents,这将暂停执行并强制主线程清空消息泵并路由所有未完成的请求。

+0

谢谢,这是我的情况,并Application.DoEvents()做了伎俩。 – Tate 2012-03-20 10:23:43

0

我发现的是,控件的实际绘制/绘制可能会非常缓慢,尤其是如果您有大量的控件和/或使用双缓冲来平滑刷新。我正在使用BeginInvoke从我从套接字接收到的数据更新列表视图控件。有时更新发生得如此之快以至于它冻结了应用程序。我通过将异步收到的所有套接字写入队列,然后在单独的线程中使数据出队,并使用列表视图上的开始更新结束更新来解决此问题,并完成所有未完成的更新。这削减了大量额外的重绘工作,使应用程序响应更多。

0

你必须使用BeginInvoke inested Invoke看到这个Link