• 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
  • 相关阅读:
    $().click()和$(document).on("click","selector",function(){})的区别
    orm 常用字段及参数
    前端vue 跨组件传参,cokies,axion
    drf 异常 响应 解析 三大模块
    drf 视图家族
    表断关系,和modlesserializers序列化,反序列化
    drf ___jwt插件
    drf 排序过滤分页
    django drf cors 跨域问题
    redis 数据库
  • 原文地址:https://www.cnblogs.com/zhuyingchun/p/9592351.html
Copyright © 2020-2023  润新知