BeginInvoke 的性能影响
我继承了从主线程(不是后台线程,这通常是模式)调用 BeginInvoke 的代码。我试图了解它在这种情况下的实际作用。
BeginInvoke 中调用的方法是否会进入到窗口的消息队列中?文档说异步
,所以这是我的假设。
框架如何确定何时启动 BeginInvoke 调用的方法的优先级?
编辑:代码如下所示:
System.Action<bool> finalizeUI = delegate(bool open)
{
try
{
// do somewhat time consuming stuff
}
finally
{
Cursor.Current = Cursors.Default;
}
};
Cursor.Current = Cursors.WaitCursor;
BeginInvoke(finalizeUI, true);
这是在 Form_Load 事件中发生的。
I've inherited code where BeginInvoke is called from the main thread (not a background thread, which is usually the pattern). I am trying to understand what it actually does in this scenario.
Does the method being called in the BeginInvoke get in line of messages that come down to the window? The docs say asynchronously
, so that is my assumption.
How does the framework prioritize when to kick off the method called by BeginInvoke?
Edit: The code looks like this:
System.Action<bool> finalizeUI = delegate(bool open)
{
try
{
// do somewhat time consuming stuff
}
finally
{
Cursor.Current = Cursors.Default;
}
};
Cursor.Current = Cursors.WaitCursor;
BeginInvoke(finalizeUI, true);
This is happening in the Form_Load event.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
编辑
现在我们看到了代码,很明显这只是将一些初始化移出 Form_Load 的一种方法,但仍然会在用户与表单交互之前发生。
对
BeginInvoke
的调用位于 Form_load 内部,并且不会在其他对象上调用,因此这是对 Form.BeginInvoke 的调用。所以发生的事情是这样的。下面的原始帖子
我取决于您调用 BeginInvoke 的对象。如果该对象派生自
Control
,则 Control.BeginInvoke 将在创建控件的线程上运行。请参阅 JaredPar 的回答。但是 BeginInvoke 还有另一种使用模式。如果该对象是委托,则 BeginInvoke 在单独的线程上运行回调,该线程可能是专门为此目的而创建的。
此模式是从主线程而不是从后台线程调用 BeginInvoke 的原因之一。
edit
Now that we see the code, it's clear that this is just a way to move some initialization out of Form_Load but still have it happen before the user can interact with the form.
The call to
BeginInvoke
is inside Form_load, and is not called on another object, so this is a call to Form.BeginInvoke. So what's happening is this.original post below
I depends on the object that you call BeginInvoke on. If the object is derived from
Control
then Control.BeginInvoke will run on the thread that created the control. See JaredPar's answer.But there is another pattern for the use of BeginInvoke. if the object is a delegate, then BeginInvoke runs the callback on a separate thread, one that may be created specifically for that purpose.
This pattern is one reason that BeginInvoke is called from the main thread rather than from a background thread.
在 UI 线程上调用 BeginInvoke 的情况下,它仍然会经历将 Windows 消息发布到消息队列的过程,消息将在消息队列中等待处理。处理消息时委托将运行。该消息的优先级与从后台线程调用的消息不同。
In the case BeginInvoke is called on a UI thread it will still go through the process of posting a Windows Message to the message queue where the message will wait to be processed. The delegate will run when the message is processed. This message is not prioritized in any way that's different than it being called from the background thread.
在这种情况下,我怀疑调用看起来像这样:
发生的情况是一些代码将在线程池线程上运行,并更新创建控件的线程上的控件,而如果使用 Control.Invoke, 一些代码将在创建控件的线程上运行,并更新该线程上的控件。
In this scenario I suspect the call looks like:
What's happening is that some code will run on on a threadpool thread, and update the control on the thread that created the control whereas if Control.Invoke was used, some code would run on the thread that created the control, and update the control on that thread as well.
在广泛使用 BackgroundWorker 之前,您必须先同步回 UI 线程,然后才能对 UI 线程上创建的控件(即几乎每个控件)执行任何操作。
这里有一个非常好的参考示例在“对 Windows 窗体控件的线程安全调用”部分中。
Prior to widespread BackgroundWorker use, you had to synchronize back to the UI thread before doing any operations on Controls created on the UI thread (i.e. pretty much every Control).
There's a pretty good reference example here down in the "Thread-Safe Calls to a Windows Forms Control" section.