Good article on BeginInvoke and Invoke differences
Here is a code template for it. On the GUI class (form or control derived object):
Here is a code template for it. On the GUI class (form or control derived object):
private delegate void DataChanged(Object Sender, BindingEventArgs Args); private void HandleDataChanged(Object Sender, BindingEventArgs Args) { // If this delegate is invoked on another thread if (this.InvokeRequired) { // Asynchronously call THIS method later // but this time on our own GUI thread // BeginInvoke translates to a PostMessage call on // our window. BeginInvoke(new DataChangedDelegate(HandleDataChanged), new object[] { Sender, Args }); } else // when the method is invoked on the GUI thread { // Update our forms/controls as required UpdateGui(Args); } }Simpler form of the InvokeRequired/BeginInvoke or Invoke pattern using the MethodInvoker
private void OnHandleDataChanged() { // If this delegate is invoked on another thread if (this.InvokeRequired) { // Asynchronously call THIS method later // but this time on our own GUI thread // BeginInvoke translates to a PostMessage call on // our window. // Invoke maps to a SendMessage call, it will BLOCK // the calling thread until finished BeginInvoke/Invoke(new MethodInvoker(HandleDataChanged)); } else // when the method is invoked on the GUI thread { // Update our forms/controls as required } }Simplest InvokeRequired Pattern, again this is within the GUI object:
// Define the delegate private delegate void SomeDelegate(string arg1, int arg2); // or (easier) use Action<string, int>, see below private void HandleDataChanged(string arg1, int arg2) { // IF this delegate is invoked on another thread if (this.InvokeRequired) { // THEN Call it again asynchronously on the GUI thread this.BeginInvoke( new Action<string, int>(HandleDataChanged), // Make sure the number of args here matches the number // of args in the delegate! new object[] { arg1, arg2 }); return; } // From this point onwards we are definitely on the GUI thread again // Update our forms/controls as required ... }As a rule use BeginInvoke unless Synchronization is critical when marshalling to the GUI thread. Note that BeginInvoke() in this context (marshalling to a GUI thread) is a fire and forget thing, no need to call EndInvoke() and all that shenanigans.
No comments:
Post a Comment