[英]Control.Invoke() hangs application
I'm showing an animation while my control is loading the data. 我正在控制加载数据时显示动画。 When the thread finishes, I hide the animation and show the control.
线程完成后,我隐藏动画并显示控件。 So I'm executing this code from a thread:
所以我从一个线程执行这个代码:
protected void InvokeEnableBackControl()
{
if (this.InvokeRequired)
{
this.Invoke(new OpHandler(EnableBackControl));
}
else
{
EnableBackControl();
}
}
Sometimes, when I execute this code, the main thread gets hanged in the following code: 有时,当我执行此代码时,主线程在以下代码中被挂起:
protected virtual void EnableBackControl()
{
if (overlayAnimation.TargetControl != null)
{
overlayAnimation.TargetControl.BringToFront();
}
overlayAnimation.SendToBack();
overlayAnimation.Enabled = false;
overlayAnimation.Visible = false;
} }
I'm not sure if it's hanged setting the Enable
or Visible
property. 我不确定是否挂起设置
Enable
或Visible
属性。 Do you know any circumstance that may hand the application calling these properties from a Control.Invoke
? 你知道任何可以从
Control.Invoke
手动调用这些属性的应用程序的情况吗?
Note that Control.Invoke
is synchronous, so it will wait for EnableBackControl()
to return. 请注意,
Control.Invoke
是同步的,因此它将等待EnableBackControl()
返回。 Consider using Control.BeginInvoke
, which you can "fire and forget." 考虑使用
Control.BeginInvoke
,你可以“发射并忘记”。
See this answer: What's the difference between Invoke() and BeginInvoke() 看到这个答案: Invoke()和BeginInvoke()之间有什么区别
I've run into problems before when I'm executing .Invoke on a background thread while my main thread is still busy - this gives the impression that the app is hung, because the .Invoke just sits there, waiting for the main thread to respond that it's paying attention. 我在执行之前遇到了问题。当我的主线程仍然忙时,在后台线程上调用 - 这给人的印象是应用程序挂起,因为.Invoke只是坐在那里,等待主线程到回应它正在关注。 Possible causes:
可能的原因:
When you attach the debugger, pay special attention to what your main control MessagePump thread is doing - I suspect its lack of attention is the cause of your trouble. 当您附加调试器时,请特别注意您的主控制MessagePump线程正在做什么 - 我怀疑它缺乏关注是您的麻烦的原因。 If you identify that it's a tight loop in your main thread that's not responding, try inserting a
.DoEvents
in the loop, which will pause execution and force the main thread to empty the message pump and route any outstanding requests. 如果您确定它是主线程中没有响应的紧密循环,请尝试在循环中插入
.DoEvents
,这将暂停执行并强制主线程清空消息泵并路由任何未完成的请求。
在调试中运行,使应用程序挂起,然后在Visual Studio中暂停调试并检查线程。
What I discovered is that the actual drawing/painting of controls can be quite slow, esp if you have a lot of them and/or use double buffering for smooth refresh. 我发现控件的实际绘图/绘画可能非常慢,特别是如果你有很多它们和/或使用双缓冲来平滑刷新。 I was using BeginInvoke to update a listview control from data I was receiving from a socket.
我正在使用BeginInvoke从我从套接字接收的数据更新listview控件。 At times the updates were happening so fast that it was freezing the app up.
有时更新发生得如此之快,以至于冻结了应用程序。 I solved this by writing everything I received in the sockets async receive to a queue, and then in a seperate thread dequeuing the data and using BeginUpdate and EndUpdate on the listview and doing all the outstanding updates in between.
我通过将在套接字async接收中收到的所有内容写入队列,然后在单独的线程中将数据出列并在listview上使用BeginUpdate和EndUpdate并在其间执行所有未完成的更新来解决这个问题。 This cut out a ton of the extra redrawing and made the app a lot more responsive.
这减少了大量的额外重绘,使应用程序响应更快。
您必须使用BeginInvoke
inested Invoke
才能看到此链接
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.