[英]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;
}
我不确定是否挂起设置Enable
或Visible
属性。 你知道任何可以从Control.Invoke
手动调用这些属性的应用程序的情况吗?
请注意, Control.Invoke
是同步的,因此它将等待EnableBackControl()
返回。 考虑使用Control.BeginInvoke
,你可以“发射并忘记”。
看到这个答案: Invoke()和BeginInvoke()之间有什么区别
我在执行之前遇到了问题。当我的主线程仍然忙时,在后台线程上调用 - 这给人的印象是应用程序挂起,因为.Invoke只是坐在那里,等待主线程到回应它正在关注。 可能的原因:
当您附加调试器时,请特别注意您的主控制MessagePump线程正在做什么 - 我怀疑它缺乏关注是您的麻烦的原因。 如果您确定它是主线程中没有响应的紧密循环,请尝试在循环中插入.DoEvents
,这将暂停执行并强制主线程清空消息泵并路由任何未完成的请求。
在调试中运行,使应用程序挂起,然后在Visual Studio中暂停调试并检查线程。
我发现控件的实际绘图/绘画可能非常慢,特别是如果你有很多它们和/或使用双缓冲来平滑刷新。 我正在使用BeginInvoke从我从套接字接收的数据更新listview控件。 有时更新发生得如此之快,以至于冻结了应用程序。 我通过将在套接字async接收中收到的所有内容写入队列,然后在单独的线程中将数据出列并在listview上使用BeginUpdate和EndUpdate并在其间执行所有未完成的更新来解决这个问题。 这减少了大量的额外重绘,使应用程序响应更快。
您必须使用BeginInvoke
inested Invoke
才能看到此链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.