How to use BeginInvoke C#
Asked Answered
L

2

64

Could you explain this for me please:

someformobj.BeginInvoke((Action)(() =>
{
    someformobj.listBox1.SelectedIndex = 0;
}));

Could you tell me how can I use begininvoke exactly? What is Action type? Why there is blank brackets ()? And what does this mean =>?

Luxurious answered 17/1, 2013 at 21:7 Comment(2)
so many different questions in one post... - there should be at least 3 separate questionsBeefwood
Take a look at this article as well mark-dot-net.blogspot.com.uy/2014/07/…Venesection
C
91

Action is a Type of Delegate provided by the .NET framework. The Action points to a method with no parameters and does not return a value.

() => is lambda expression syntax. Lambda expressions are not of Type Delegate. Invoke requires Delegate so Action can be used to wrap the lambda expression and provide the expected Type to Invoke()

Invoke causes said Action to execute on the thread that created the Control's window handle. Changing threads is often necessary to avoid Exceptions. For example, if one tries to set the Rtf property on a RichTextBox when an Invoke is necessary, without first calling Invoke, then a Cross-thread operation not valid exception will be thrown. Check Control.InvokeRequired before calling Invoke.

BeginInvoke is the Asynchronous version of Invoke. Asynchronous means the thread will not block the caller as opposed to a synchronous call which is blocking.

Carbajal answered 17/1, 2013 at 21:20 Comment(3)
So if I understand this correctly, Action is used to guarantee cross-thread safety, so you would inform the object via the method call instead of setting the value yourself? Also, the method will accept ANY delegate, not just an Action specifically, yes?Predicative
@KyleBaran - Action is unrelated to thread safety, that's Invoke. Invoke accepts a Delegate as a parameter. So anything convertible to a Delegate can be passed as a parameter.Carbajal
@KyleBaran Action is just a built-in delegate type, you can just replace it with: delegate void mydlg(); Invoke((mydlg)(() => { }));Unipersonal
S
15

I guess your code relates to Windows Forms.
You call BeginInvoke if you need something to be executed asynchronously in the UI thread: change control's properties in most of the cases.
Roughly speaking this is accomplished be passing the delegate to some procedure which is being periodically executed. (message loop processing and the stuff like that)

If BeginInvoke is called for Delegate type the delegate is just invoked asynchronously.
(Invoke for the sync version.)

If you want more universal code which works perfectly for WPF and WinForms you can consider Task Parallel Library and running the Task with the according context. (TaskScheduler.FromCurrentSynchronizationContext())

And to add a little to already said by others: Lambdas can be treated either as anonymous methods or expressions.
And that is why you cannot just use var with lambdas: compiler needs a hint.

UPDATE:

this requires .Net v4.0 and higher

// This line must be called in UI thread to get correct scheduler
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();

// this can be called anywhere
var task = new System.Threading.Tasks.Task( () => someformobj.listBox1.SelectedIndex = 0);

// also can be called anywhere. Task  will be scheduled for execution.
// And *IF I'm not mistaken* can be (or even will be executed synchronously)
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler);

If you started the task from other thread and need to wait for its completition task.Wait() will block calling thread till the end of the task.

Read more about tasks here.

Selfgoverned answered 17/1, 2013 at 21:15 Comment(1)
could u give me some examples please ?Luxurious

© 2022 - 2024 — McMap. All rights reserved.