Control.BeginInvoke () Vs Dispatcher Vs SynchronizationContext Vs .. - RELIABILITY

Calling a UI thread from a workflow has been discussed many times, and we know why to use BeginInvoke () instead of Invoke (). I recently posted this question , and after several studies, I found out that there are at least three different ways (inside they can be the same) to call (asynchronously) something in the user interface thread.

  • Control.BeginInvoke()
  • Using SynchronizatoinContext Class
  • Using Dispatcher.BeginInvoke(priority.. )

Can someone tell me what is a RELIABLE way to asynchronously call a method that will execute in the user interface thread. Any experience? I see Dispatcher.BeginInvoke has a priority component for it, makes it more reliable?

Context :
we use someControl.BeginInvoke() , but noticed that sometimes (unfortunately, only in the working environment of the end user) the delegate passed to BeginInvoke is never executed, which makes me believe that the message of the message that it creates is lost. We need a reliable way to communicate with the user interface stream. control.Invoke() sometimes hangs the user interface, so we also don’t want to go there.

+6
source share
3 answers

They work as they should, if you call BeginInvoke , and sometimes nothing happens, there is some problem in the environment or the calling code, maybe this is not what BeginInvoke unreliable. Well, it could be a mistake, but it is much less likely.

Perhaps you could give more context, and we can help diagnose.

0
source

SynchronizationContext is more abstract and adaptable in the larger case. This is the shell of a specific implementation. MSDN says: "Synchronization model providers can extend this class and provide their own implementations for these methods."

0
source

You have to be careful with the lambda and BeginInvoke functions. I had code that led to all kinds of weird behavior.

 MyThing thing; while( GetThing(ref thing)) { control.BeginInvoke((Action)(() => control.Text = thing.ToString())); } 

The problem is that thing not evaluated when creating a lambda function. It is evaluated when performing the lamdba function. But it is tied to a variable that changes at the same time in the producer thread.

You can fix this problem by declaring a copy of the thing local variable

 MyThing thing; while( GetThing(ref thing)) { MyThing thing_x = thing; control.BeginInvoke((Action)(() => control.Text = thing_x.ToString())); } 

Or you can put a BeginInvoke lesson in a wrapper

 MyThing thing; while( GetThing(ref thing)) { SetText(thing); } void SetText(MyThing thing) control.BeginInvoke((Action)(() => control.Text = thing.ToString())); } 
0
source

Source: https://habr.com/ru/post/890414/


All Articles