当我的控件正在加载数据时,我正在显示动画。线程完成后,我隐藏动画并显示控件。所以我从一个线程执行这段代码:
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
调用这些属性?
答案 0 :(得分:17)
请注意Control.Invoke
是同步的,因此会等待EnableBackControl()
返回。考虑使用Control.BeginInvoke
,您可以“发射并忘记”。
请参阅此答案:What's the difference between Invoke() and BeginInvoke()
答案 1 :(得分:7)
我在执行之前遇到了问题。当主线程仍然忙时,在后台线程上调用 - 这给人的印象是应用程序挂起,因为.Invoke只是坐在那里,等待响应它正在关注的主线程。可能的原因:
当您附加调试器时,请特别注意您的主控制MessagePump线程正在做什么 - 我怀疑它缺乏关注是您的麻烦的原因。如果您确定主线程中的响应循环没有响应,请尝试在循环中插入.DoEvents
,这将暂停执行并强制主线程清空消息泵并路由任何未完成的请求。
答案 2 :(得分:4)
在debug中运行,make app hang,然后在Visual Studio中暂停调试并检查线程。
答案 3 :(得分:0)
我发现控制的实际绘制/绘制可能非常慢,特别是如果你有很多这样的和/或使用双缓冲来平滑刷新。我正在使用BeginInvoke从我从套接字接收的数据更新listview控件。有时更新发生得如此之快,以至于冻结了应用程序。我通过将套接字异步接收中收到的所有内容写入队列,然后在单独的线程中将数据出列并在列表视图上使用 BeginUpdate 和 EndUpdate 进行解决,从而解决了这个问题。所有未完成的更新。这减少了大量的额外重绘,使应用程序响应更快。
答案 4 :(得分:0)
您必须使用BeginInvoke
inested Invoke
查看此Link