zoukankan      html  css  js  c++  java
  • System.Windows.Forms.Control.Invoke与BeginInvoke

    WinForm的UI对象只能在UI线程中操作,在非UI线程中操作UI对象,会引发不可预知的错误,这时就需要用到Control.Invoke或者Control.BeginInvoke。

    用户线程调用Control.BeginInvoke会向UI消息队列发送一个带委托消息,Control.BeginInvoke不会阻塞用户线程,直接返回IAsyncResult对象。

    用户线程调用Control.EndInvoke(IAsyncResult),Control.EndInvoke会阻塞用户线程,直到委托执行完成,并返回委托的返回值。没有返回值返回null。

    Control.Invoke相当于Control.BeginInvoke和Control.EndInvoke的合体,会阻塞用户线程,直到委托执行完成,并返回委托的返回值。没有返回值返回null。

    根据类继承关系,在窗口中可以直接使用BeginInvoke、EndInvoke、Invoke。

    System.Object
      System.MarshalByRefObject
        System.ComponentModel.Component
          System.Windows.Forms.Control
            System.Windows.Forms.ScrollableControl
              System.Windows.Forms.ContainerControl
                System.Windows.Forms.Form

    实验示例:

    窗体:

    代码:

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                // 在非UI线程中操作UI对象,调试运行会报错。
                // 直接运行会使程序置于不可预知风险之中。
                new Thread(() =>
                {
                    progressBar1.Value = 100;
                }).Start();
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                new Thread(() => {
                    var result = this.Invoke(new Func<int, int, string>((n1, n2) =>
                    {
                        for(int i = 0; i <= 100; i += 10)
                        {
                            progressBar1.Value = i;
                            Thread.Sleep(200);
                        }
                        return (n1+n2).ToString();
                    }), 100, 21);
                    MessageBox.Show(result.GetType().ToString() + ":" + result);
                }).Start();
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                new Thread(() =>
                {
                    IAsyncResult asyncResult = this.BeginInvoke(new Func<int, int, string>((n1, n2) =>
                    {
                        for (int i = 0; i <= 100; i += 10)
                        {
                            progressBar1.Value = i;
                            Thread.Sleep(200);
                        }
                        return (n1 + n2).ToString();
                    }), 200, 32);
                    MessageBox.Show("BeginInvoke不会阻塞");
                    var result = this.EndInvoke(asyncResult);
                    MessageBox.Show("EndInvoke会阻塞," + result.GetType().ToString() + ":" + result);
                }).Start();
            }
    
            private void button4_Click(object sender, EventArgs e)
            {
                // 连续给两个委托,由于UI线程只有一个,两个委托只能先后执行
                new Thread(() =>
                {
                    IAsyncResult asyncResult1 = this.BeginInvoke(new Func<int, int, string>((n1, n2) =>
                    {
                        for (int i = 0; i <= 100; i += 10)
                        {
                            progressBar1.Value = i;
                            Thread.Sleep(200);
                        }
                        return (n1 + n2).ToString();
                    }), 200, 32);
                    IAsyncResult asyncResult2 = this.BeginInvoke(new Func<int, int, string>((n1, n2) =>
                    {
                        for (int i = 0; i <= 100; i += 10)
                        {
                            progressBar2.Value = i;
                            Thread.Sleep(200);
                        }
                        return (n1 + n2).ToString();
                    }), 400, 64);
                    MessageBox.Show("BeginInvoke不会阻塞");
                    var result1 = this.EndInvoke(asyncResult1);
                    MessageBox.Show("EndInvoke(asyncResult1)返回");
                    var result2 = this.EndInvoke(asyncResult2);
                    MessageBox.Show("EndInvoke(asyncResult2)返回");
                    MessageBox.Show(
                        result1.GetType().ToString() + ":" + result1 + "
    " +
                        result2.GetType().ToString() + ":" + result2);
                }).Start();
            }
    
            private void button5_Click(object sender, EventArgs e)
            {
                // 要等精度条更新完成后,点击才能响应
                MessageBox.Show("ha");
            }
    
            private void button6_Click(object sender, EventArgs e)
            {
                progressBar1.Value = 0;
                progressBar2.Value = 0;
            }
        }
    View Code
  • 相关阅读:
    原生js设置cookie
    vuex数据持久化存储
    export和export default的区别
    userAgent判断是微信还是企业微信
    SVN的使用方法
    Js字符串反转
    通用JS10——一元加和减
    通用JS十——递增/递减操作符
    通用JS9
    @SuppressWarning注解用法
  • 原文地址:https://www.cnblogs.com/zhuyingchun/p/9592351.html
Copyright © 2011-2022 走看看