简体   繁体   English

Invoke和BeginInvoke

[英]Invoke and BeginInvoke

Greetings, I am developing some application in C#. 问候,我正在用C#开发一些应用程序。 At the moment I'm dealing with threading and I have a question that I have in my mind. 目前我正在处理线程,我有一个问题,我在脑海里。 What is the difference between Invoke and BeginInvoke? Invoke和BeginInvoke有什么区别? I read some thread and I found some useful information here: here 我读了一些帖子,我在这里找到了一些有用的信息: 这里

However what is the difference between Invoke and BeginInvoke in the following code: 但是,以下代码中的Invoke和BeginInvoke之间有什么区别:

private void ProcessRoutine()
{
   for (int nValue = StartFrom; nValue <= EndTo; nValue++)
   {
      this.Invoke(this.MyDelegate, nValue);
      //this.BeginInvoke(this.MyDelegate, nValue);
   }
   MessageBox.Show("Counting complete!");
}
private void MessageHandler(int progress)
{
    lblStatus.Text = lblStatus.Text = "Processing item: " + progress.ToString();
    progressBar1.Value = progress;
}

where MyDelegate is a reference to MessageHandler function. 其中MyDelegate是对MessageHandler函数的引用。

I noticed that using BeginInvoke lblStatus.Text is not refreshed where using Invoke refreshes the label. 我注意到使用BeginInvoke lblStatus.Text没有刷新,使用Invoke刷新标签。 Additionally I know that Invoke waits for its execution to complete. 另外我知道Invoke等待它的执行完成。 The most important case I'm interested in is why there is a difference in refreshing label text in this case. 我感兴趣的最重要的案例是为什么在这种情况下刷新标签文本有所不同。

To begin, from your link: 首先,从您的链接:

  • Control.Invoke : Executes on the UI thread, but calling thread waits for completion before continuing. Control.Invoke :在UI线程上执行,但调用线程在继续之前等待完成。
  • Control.BeginInvoke : Executes on the asynchronous UI thread, and calling thread doesn't wait for completion. Control.BeginInvoke :在异步UI线程上执行,并且调用线程不等待完成。

and from MSDN: 从MSDN:

BeginInvoke executes the specified delegate asynchronously on the thread that the control's underlying handle was created on. BeginInvoke在创建控件的基础句柄的线程上异步执行指定的委托。

To sum it up, BeginInvoke is asynchronous . 总结一下, BeginInvoke异步的 When BeginInvoke is called from the UI thread the request will be executed in parallel with the UI thread. 从UI线程调用BeginInvoke ,请求将与UI线程并行执行。 Which means it may not execute until after the currently executing method has returned. 这意味着它可能直到当前正在执行的方法返回后才执行。 So in this case the text box will never appear to update because the for loop will not be interrupted, as the calling thread will not wait for this event to be completed before continuing. 因此,在这种情况下,文本框将永远不会更新,因为for循环不会被中断,因为调用线程不会等待此事件在继续之前完成。

Alternatively, Invoke is synchronous . 或者, Invoke同步的 The text box will be updated because the calling thread will wait for the call to complete before continuing execution. 文本框将被更新,因为调用线程将在继续执行之前等待调用完成。

With Invoke the method gets executed and the application waits for it to complete. 使用Invoke,方法将被执行,应用程序将等待它完成。

With BeginInvoke the method is invoked Asychnronously and the application continues to execute while the method referenced in BeginInvoke is executed. 使用BeginInvoke,方法被Asychnronously调用,应用程序继续执行,同时执行BeginInvoke中引用的方法。

With BeginInvoke you need to call EndInvoke to get the results of the method you executed using BeginIvnoke. 使用BeginInvoke,您需要调用EndInvoke来获取使用BeginIvnoke执行的方法的结果。

You should not update GUI components in BeginXXX methods as they are run in another thread to the GUI thread, contrary to your Invoke method. 您不应该更新BeginXXX方法中的GUI组件,因为它们在另一个线程中运行到GUI线程,这与您的Invoke方法相反。 You cannot access GUI components in a different thread to the GUI thread. 您无法在与GUI线程不同的线程中访问GUI组件。

Hope this helps! 希望这可以帮助!

Control.BeginInvoke doesn't work on a different thread (or threadpool), a delegate.BeginInvoke does. Control.BeginInvoke不能在不同的线程(或线程池)上工作,委托.BeginInvoke也可以。 MSDN's one liner says: MSDN的一个班轮说:

Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on. 在创建控件的基础句柄的线程上异步执行指定的委托。

However Control.BeginInvoke simply uses PostMessage and returns - no CLR Thread is created. 但是, Control.BeginInvoke只使用PostMessage并返回 - 没有创建CLR Thread

The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message. PostMessage函数将消息放入(发布)与创建指定窗口的线程关联的消息队列中,并返回而不等待线程处理消息。

This article summarises whether to use Invoke or BeginInvoke quite well: 本文总结了是否要很好地使用InvokeBeginInvoke

Which function to use, you ask. 你问哪个功能。 It really depends on your requirement. 这真的取决于你的要求。 If you want your UI update to complete before proceeding, you use Invoke. 如果您希望在继续之前完成UI更新,则使用Invoke。 If there is no such requirement, I'd suggest using BeginInvoke, as it makes the thread calling it seemingly "faster". 如果没有这样的要求,我建议使用BeginInvoke,因为它使得调用它的线程看起来“更快”。 There are a few gotcha's with BeginInvoke though. 但是有一些关于BeginInvoke的问题。

  • If the function you are calling via BeginInvoke accesses shared state (state shared between the UI thread and other threads), you are in trouble. 如果您通过BeginInvoke调用的函数访问共享状态(UI线程和其他线程之间共享的状态),则表示您遇到了麻烦。 The state might change between the time you called BeginInvoke and when the wrapped function actually executes, leading to hard to find timing problems. 状态可能会在您调用BeginInvoke和实际执行包装函数之间发生变化,从而导致很难找到计时问题。
  • If you are passing reference parameters to the function called via BeginInvoke, then you must make sure that no one else modifies the passed object before the function completes. 如果要将引用参数传递给通过BeginInvoke调用的函数,则必须确保在函数完成之前没有其他人修改传递的对象。 Usually, people clone the object before passing it to BeginInvoke, which avoids the problem altogether. 通常,人们在将对象传递给BeginInvoke之前克隆该对象,这完全避免了这个问题。

BeginInvoke executes the method body on another thread and allows the current thread to continue. BeginInvoke在另一个线程上执行方法体,并允许当前线程继续。 If you are trying to directly update a control property from another thread, it will throw an exception. 如果您尝试直接从另一个线程更新控件属性,它将引发异常。

This basically boils down to whether or not you want the control to be updated synchronously or asynchronously. 这基本上归结为您是否希望同步或异步更新控件。 This all depends on your specific situation. 这一切都取决于您的具体情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM