Call (delegate)

Can someone explain this expression written on this link

Invoke(Delegate): 

Runs the specified delegate in the thread that owns the base window control handle .

Can someone explain what this means (especially brave), I can't figure it out.

+67
c # invoke winforms delegates
05 Feb '13 at 9:09
source share
9 answers

The answer to this question is how C # Controls work

The controls in Windows Forms are tied to a specific thread and are not a safe thread. Therefore, if you call the control method from another thread, you must use one of the control call methods to marshal the call to the appropriate topic. This property can be used to determine if you should invoke the invoke method, which can be useful if you don’t know which stream belongs to the control.

From Control.InvokeRequired

Effectively, what Invoke does ensures that the code you invoke occurs in the thread that the control lives in, effectively preventing cross-thread exceptions.

From a historical point of view, in .Net 1.1, this was actually permitted. This means that you can try and execute the code in the "GUI" thread from any background thread, and this will work mostly. Sometimes it just made your application crash because you actually messed up the GUI thread while it was doing something else. This is a Cross Threaded Exception - imagine you are trying to update a TextBox while the GUI is drawing something else.

  • Which action takes precedence?
  • Is it possible for both to happen at once?
  • What happens to all the other commands that the GUI should execute?

Effectively, you are interrupting a queue, which can have many unforeseen consequences. Invoke is a “polite” way to get what you want to do in this queue, and this rule has been enforced with .Net 2.0 using the thrown InvalidOperationException .

To understand what is really going on behind the scenes, and what is meant by a “graphics stream,” it’s useful to understand what Message Pump or Message Loop is.

In fact, this already answered the question " What is Message Pump " and it is recommended to read to understand the real mechanism that you communicate with when interacting with controls.

Other readings that may prove useful include:

What happens to Begin Invoke

One of the basic rules for programming the Windows GUI is that only the thread that created the control can access and / or change its contents (with the exception of a few documented exceptions). Try to do this from any other and you will get unpredictable behavior, from a deadlock to an exception to half the updated user interface. The correct way to update management from another thread is to send the corresponding message to the application message queue. When the message pump comes close to executing this message, the control will be updated on the same thread that created it (remember that the message pump runs on the main thread).

and for a more detailed overview of representative sample code:

Invalid multi-thread operations

 // the canonical form (C# consumer) public delegate void ControlStringConsumer(Control control, string text); // defines a delegate type public void SetText(Control control, string text) { if (control.InvokeRequired) { control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text}); // invoking itself } else { control.Text=text; // the "functional part", executing only on the main thread } } 

Once you get an InvokeRequired score, you might consider using an extension method to transfer these calls. This is well described in the question about stack overflow. Clearing code populated by Invoke Required . "

There is also a story of a story that may be interesting .

+97
Feb 05 '13 at 9:15
source share

A control or window in Windows Forms is just the shell of a Win32 window identified by a handle (sometimes called HWND). Most of the things you do with the control will ultimately result in a call to the Win32 API that uses this handle. The handle belongs to the thread that created it (usually the main thread) and should not be processed by another thread. If for some reason you need to do something using a control from another thread, you can use Invoke to ask the main thread to do this on your behalf.

For example, if you want to change the label text from a workflow, you can do something like this:

 theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!")); 
+53
Feb 05 '13 at 9:13
source share

If you want to change the control, this must be done in the stream in which the control was created. This Invoke method allows you to execute methods in a linked thread (the thread that owns the control underlying the window).

In the example below, thread1 throws an exception because SetText1 is trying to change textBox1.Text from another thread. But in thread2, the Action in SetText2 is executed on the thread in which the TextBox was created.

 private void btn_Click(object sender, EvenetArgs e) { var thread1 = new Thread(SetText1); var thread2 = new Thread(SetText2); thread1.Start(); thread2.Start(); } private void SetText1() { textBox1.Text = "Test"; } private void SetText2() { textBox1.Invoke(new Action(() => textBox1.Text = "Test")); } 
+17
Feb 05 '13 at 9:20
source share

Call ((MethodInvoker) delegate {textBox1.Text = "Test";});

+3
Dec 12 '16 at 0:47
source share

In practice, this means that the delegate is guaranteed to be called in the main thread. This is important because in the case of Windows controls, if you do not update your properties in the main thread, you either do not see the change or the control throws an exception.

Sample:

 void OnEvent(object sender, EventArgs e) { if (this.InvokeRequired) { this.Invoke(() => this.OnEvent(sender, e); return; } // do stuff (now you know you are on the main thread) } 
+2
Feb 05 '13 at 9:14
source share

This means that the delegate will run in the user interface thread, even if you call this method from a background worker or thread thread. User interface elements are similar to threads - they like to talk directly to one thread: the user interface thread. A user interface thread is defined as the thread that created the control instance, and therefore is associated with a window handle. But all this is implementation detail.

The key point is that you call this method from the workflow so that you can access the user interface (to change the value on the shortcut, etc.) - since you are not allowed to do that from any other thread except the user interface thread .

+1
Feb 05 '13 at 9:13
source share

this.Invoke(delegate) make sure you call the delegate with this.Invoke() with the main thread / created thread.

I can say that the Thumb rule does not have access to form controls other than the main thread.

Perhaps the following lines make sense to use Invoke ()

  private void SetText(string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } } 

There are situations, although you create a Threadpool thread (worker thread) that will run in the main thread. It will not create a new coz thread for the main thread, available for processing further instructions. So, first we examine whether the current current thread is the main thread using this.InvokeRequired , if it returns true, the current code works in the work thread, so call this.Invoke (d, new object [] {text});

else directly updates the user interface control (here you are guaranteed that you are using the main thread code.)

+1
Feb 10 '14 at 5:49
source share

Delegation is essentially a built-in Action or Func<T> . You can declare a delegate outside the scope of the method you are using, or using the lambda ( => ) expression; because you run the delegate as part of the method, you run it in a thread that runs for the current window / application, which is in bold.

Lambda example

 int AddFiveToNumber(int number) { var d = (int i => i + 5); d.Invoke(number); } 
0
Feb 05 '13 at 9:13
source share

This means that the delegate you are passing is executed in the thread that created the Control object (which is the user interface thread).

You need to call this method when your application is multithreaded, and you want to perform some user interface operation from a thread other than the user interface thread, because if you just try to call the method in the control from another thread, get a System.InvalidOperationException.

0
Feb 05 '13 at 9:14
source share



All Articles