C# BeginInvoke / Invoke

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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值