C# BeginInvoke / Invoke

  • Post author:
  • Post category:其他




1.Control下调用



1.1 在主线程调用
            listBox1.Items.Add("--begin--");
            listBox1.Invoke(new Action(() =>
            {
                listBox1.Items.Add("Invoke");
            }));

            Thread.Sleep(1000);
            listBox1.Items.Add("--end--");

在这里插入图片描述

            listBox1.Items.Add("--begin--");
            var bi = listBox1.BeginInvoke(new Action(() =>
            {
                //Thread.Sleep(10000);
                listBox1.Items.Add("BeginInvoke");
            }));
            Thread.Sleep(1000);
            listBox1.Items.Add("--end--");

在这里插入图片描述

此时两种情况都会卡死UI的

在主线程中直接调用Invoke、BeginInvoke、EndInvoke都会造成阻塞



1.2 在子线程调用
       private void Button1_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.Name = "Main";
            listBox1.Items.Add("--begin--");
            new Thread(() =>
            {
                Thread.CurrentThread.Name = "ThreadInvoke";
                string temp = "Before!";
                listBox1.Invoke(new Action(() =>
                    {
                        Thread.Sleep(10000);
                        this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);
                    }));
                temp += "After!";
            }).Start();
            listBox1.Items.Add("--end--");
        }

在这里插入图片描述

1.listBox1.Invoke的委托其实也在主线程中执行

2.Invoke在支线程中调用也会阻塞主线程UI。

3.Invoke还会阻塞支线程。(因为输出结果中没有出现After)

       private void Button1_Click(object sender, EventArgs e)
        {

            Thread.CurrentThread.Name = "Main";

            listBox1.Items.Add("--begin--");
            new Thread(() =>
            {
                Thread.CurrentThread.Name = "ThreadBeginInvoke";
                string temp = "Before!";
                listBox1.BeginInvoke(new Action(() =>
                {
                    Thread.Sleep(10000);
                    this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);
                }));
                temp += "After!";
            }).Start();
            listBox1.Items.Add("--end--");


        }

在这里插入图片描述

1.BeginInvoke在主线程中执行。

2.BeginInvoke在支线程中调用也会阻塞主线程。

3.BeginInvoke相对于支线程是异步的,即没有阻塞支线程

总结:

Control的Invoke和BeginInvoke的委托方法是在主线程,即UI线程上执行。(也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,千万别在主线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死)

Invoke会阻塞主支线程,BeginInvoke只会阻塞主线程,不会阻塞支线程!因此BeginInvoke的异步执行是指相对于支线程异步,而不是相对于主线程异步。



2.Delegate调用

       delegate void xDel(int i);
        private void Button1_Click(object sender, EventArgs e)
        {
            Thread.CurrentThread.Name = "Main";

            listBox1.Items.Add("--begin--");
            xDel xd = new xDel(t =>
              {
                  //Thread.Sleep(t);
                  //listBox1.BeginInvoke(new Action(() =>
                  //{
                  //   listBox1.Items.Add("Invoke");
                  //}));

                  Thread.CurrentThread.Name = "ThreadBeginInvoke";
                  string temp = "Before!";
                  listBox1.BeginInvoke(new Action(() =>
                  {
                      Thread.Sleep(10000);
                      this.listBox1.Items.Add(temp += "Invoke!" + Thread.CurrentThread.Name);
                  }));
                  temp += "After!";

              });
            xd.BeginInvoke(3000, null, null);

            listBox1.Items.Add("--end--");

        }

其实这种情况跟上面new Thread是一样的,委托的beginInvoke也是开了一个线程

注:

在WPF中,写法又有点不一样,要Dispatcher.Invoke

        listBox1.Items.Add("--begin--");
        listBox1.Dispatcher.Invoke(new Action(() =>
        {
            listBox1.Items.Add("Invoke");
        }));

        Thread.Sleep(1000);
        listBox1.Items.Add("--end--");

参考:


https://www.cnblogs.com/wangshenhe/archive/2012/05/25/2516842.html



https://www.cnblogs.com/small-code/p/5732116.html


https://blog.csdn.net/goodshot/article/details/6157529


https://www.cnblogs.com/c2303191/articles/826571.html


https://blog.csdn.net/sinat_23338865/article/details/52596818


https://www.cnblogs.com/djzxjblogs/p/7525206.html



版权声明:本文为qq_36689119原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。