繁体   English   中英

Control.Invoke()挂起应用程序

[英]Control.Invoke() hangs application

我正在控制加载数据时显示动画。 线程完成后,我隐藏动画并显示控件。 所以我从一个线程执行这个代码:

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手动调用这些属性的应用程序的情况吗?

请注意, Control.Invoke是同步的,因此它将等待EnableBackControl()返回。 考虑使用Control.BeginInvoke ,你可以“发射并忘记”。

看到这个答案: Invoke()和BeginInvoke()之间有什么区别

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

  • 您的主线程被阻止等待某事
  • 您的主表单目前有一个模态对话框,因此它不会收听新请求
  • 您的主要线程正在旋转,要么不断检查某些内容是否已完成或正在进行新的工作。 在我的情况下,主线程花了第一分钟在紧密循环中旋转后台线程,因此它没有侦听来自后台线程的任何.Invoke请求。

当您附加调试器时,请特别注意您的主控制MessagePump线程正在做什么 - 我怀疑它缺乏关注是您的麻烦的原因。 如果您确定它是主线程中没有响应的紧密循环,请尝试在循环中插入.DoEvents ,这将暂停执行并强制主线程清空消息泵并路由任何未完成的请求。

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

我发现控件的实际绘图/绘画可能非常慢,特别是如果你有很多它们和/或使用双缓冲来平滑刷新。 我正在使用BeginInvoke从我从套接字接收的数据更新listview控件。 有时更新发生得如此之快,以至于冻结了应用程序。 我通过将在套接字async接收中收到的所有内容写入队列,然后在单独的线程中将数据出列并在listview上使用BeginUpdateEndUpdate并在其间执行所有未完成的更新来解决这个问题。 这减少了大量的额外重绘,使应用程序响应更快。

您必须使用BeginInvoke inested Invoke才能看到此链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM