首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BeginInvoke的性能影响

BeginInvoke的性能影响
EN

Stack Overflow用户
提问于 2010-03-19 04:56:15
回答 4查看 2.2K关注 0票数 6

我继承了从主线程(而不是后台线程,通常是模式)调用BeginInvoke的代码。我正在尝试理解它在这个场景中的实际作用。

在BeginInvoke中调用的方法是否在到达窗口的消息行中获取?医生说是asynchronously,所以这是我的假设。

框架如何确定何时启动BeginInvoke调用的方法的优先级?

编辑:代码如下:

代码语言:javascript
复制
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事件中。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-03-19 05:21:35

编辑

现在我们看到了代码,很明显,这只是一种将一些初始化移出Form_Load的方法,但仍然可以在用户与表单交互之前进行初始化。

BeginInvoke的调用在Form_load内部,并且不会在另一个对象上调用,因此这是对Form.BeginInvoke的调用。所以现在的情况是这样的。

  1. Form_Load将委托传递给Form.BeginInvoke,这会将一条消息放在表单的消息队列中,该队列位于所有用户输入消息的前面。它将光标设置为等待cursor.
  2. Form_Load返回,并允许完成窗体的其余初始化,此时窗体很可能变为可见。
  3. 一旦代码落入消息泵中,首先在队列中看到的就是该委托,因此它运行该委托。
  4. 当该委托完成时,它会将光标更改回正常的光标,

原文如下

我依赖于您调用BeginInvoke的对象。如果该对象是从Control派生的,则Control.BeginInvoke将在创建该控件的线程上运行。请参阅JaredPar的答案。

但是,还有另一种使用BeginInvoke的模式。如果该对象是一个委托,则BeginInvoke在单独的线程上运行回调,该线程可能是专门为该目的而创建的。

代码语言:javascript
复制
public class Foo
{
    ...
    public Object Bar(object arg)
    {
       // this function will run on a separate thread.
    }
}

...

// this delegate is used to Invoke Bar on Foo in separate thread, this must
// take the same arguments and return the same value as the Bar method of Foo
public delegate object FooBarCaller (object arg);

...

// call this on the main thread to invoke Foo.Bar on a background thread
//
public IAsyncResult BeginFooBar(AsyncCallback callback, object arg)
{
   Foo foo = new Foo();
   FooBarCaller caller = new FooBarCaller (foo.Bar);
   return caller.BeginInvoke (arg);
}

这种模式是从主线程而不是从后台线程调用BeginInvoke的原因之一。

票数 4
EN

Stack Overflow用户

发布于 2010-03-19 04:58:38

在UI线程上调用BeginInvoke的情况下,它仍将经历将Windows消息发送到消息队列的过程,该消息将在消息队列中等待处理。代理将在处理消息时运行。此消息不会以任何与从后台线程调用它不同的方式区分优先级。

票数 2
EN

Stack Overflow用户

发布于 2010-03-19 05:25:48

在此场景中,我怀疑调用如下所示:

代码语言:javascript
复制
private void Button1_Click(object sender, ButtonClickEventArgs e)
{
    Control.BeginInvoke(new MethodInvoker(()=> /* code etc. */));
}

发生的情况是,一些代码将在线程池线程上运行,并在创建控件的线程上更新控件,而如果使用Control.Invoke,则一些代码将在创建控件的线程上运行,并在该线程上更新控件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2473299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档