Invoke(Delegate)

2019-01-01 14:43发布

Can anybody please explain this statement written on this link

Invoke(Delegate):

Executes the specified delegate on the thread that owns the control's underlying window handle.

Can anybody explain what this means (especially the bold one) I am not able to get it clearly

9条回答
骚的不知所云
2楼-- · 2019-01-01 15:13

It means that the delegate will run on the UI thread, even if you call that method from a background worker or thread-pool thread. UI elements have thread affinity - they only like talking directly to one thread: the UI thread. The UI thread is defined as the thread that created the control instance, and is therefore associated with the window handle. But all of that is an implementation detail.

The key point is: you would call this method from a worker thread so that you can access the UI (to change the value in a label, etc) - since you are not allowed to do that from any other thread than the UI thread.

查看更多
看风景的人
3楼-- · 2019-01-01 15:14

Delegate are essentially inline Action's or Func<T>. You can declare a delegate outside the scope of a method which you are running or using a lambda expression(=>); because you run the delegate within a method, you run it on the thread which is being run for the current window/application which is the bit in bold.

Lambda example

int AddFiveToNumber(int number)
{
  var d = (int i => i + 5);
  d.Invoke(number);
}
查看更多
孤独总比滥情好
4楼-- · 2019-01-01 15:20

this.Invoke(delegate) make sure that you are calling the delegate the argument to this.Invoke() on main thread/created thread.

I can say a Thumb rule don't access your form controls except from main thread.

May be the following lines make sense for using 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 though you create a Threadpool thread(i.e worker thread) it will run on main thread. It won't create a new thread coz main thread is available for processing further instructions. So First investigate whether the current running thread is main thread using this.InvokeRequired if returns true the current code is running on worker thread so call this.Invoke(d, new object[] { text });

else directly update the UI control(Here you are guaranteed that you are running the code on main thread.)

查看更多
素衣白纱
5楼-- · 2019-01-01 15:21

It means that the delegate you pass is executed on the thread that created the Control object (which is the UI thread).

You need to call this method when your application is multi-threaded and you want do some UI operation from a thread other than the UI thread, because if you just try to call a method on a Control from a different thread you'll get a System.InvalidOperationException.

查看更多
与风俱净
6楼-- · 2019-01-01 15:27

A control or window object in Windows Forms is just a wrapper around a Win32 window identified by a handle (sometimes called HWND). Most things you do with the control will eventually result in a Win32 API call that uses this handle. The handle is owned by the thread that created it (typically the main thread), and shouldn't be manipulated by another thread. If for some reason you need to do something with the control from another thread, you can use Invoke to ask the main thread to do it on your behalf.

For instance, if you want to change the text of a label from a worker thread, you can do something like this:

theLabel.Invoke(new Action(() => theLabel.Text = "hello world from worker thread!"));
查看更多
梦醉为红颜
7楼-- · 2019-01-01 15:30

If you want to modify a control it must be done in the thread in which the control was created. This Invoke method allows you to execute methods in the associated thread (the thread that owns the control's underlying window handle).

In below sample thread1 throws an exception because SetText1 is trying to modify textBox1.Text from another thread. But in thread2, Action in SetText2 is executed in 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"));
}
查看更多
登录 后发表回答