• 1 Winform 异步更新控件


    刚才看到有人问为了winfrom中,在大数据绑定的时候出现画面假死的状态,为了解决这个问题希望通过再开一个线程来给控件绑定数据,可是画面还是会假死。
    现在看到的方法有
    1.掩耳盗铃法(Control.CheckForIllegalCrossThreadCalls = false;)
    C# code
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    using System;
    using System.Threading;
    using System.Windows.Forms;
     
    namespace ThreadTest
    {
        public partial class Form1 : Form
        {        
     
            public Form1()
            {
                InitializeComponent();
                Control.CheckForIllegalCrossThreadCalls = false;//这一行是关键      
            }
            
     
            private void btnSet_Click(object sender, EventArgs e)
            {           
                Thread t = new Thread(new ParameterizedThreadStart(SetTextBoxValue));
                t.Start("Hello World");
            }
     
     
            void SetTextBoxValue(object obj) 
            {
                this.textBox1.Text = obj.ToString();
            }        
        }
    }

    这种方法是最方便,实现最简单的方式,但是这样等于是线程之间是去了限制,子线程能够直接控制父线程的控件,会出现线程之间的冲突,不是好的实现方式
    2.利用BackgroundWorker
    C# code
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
     
    namespace ThreadTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();            
            }       
     
            private void btnSet_Click(object sender, EventArgs e)
            {
                //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
                using (BackgroundWorker bw = new BackgroundWorker())
                {
                    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                    bw.RunWorkerAsync("Hello World");
                }
            }
     
            void bw_DoWork(object sender, DoWorkEventArgs e)
            {
                //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
                e.Result = e.Argument;//这里只是简单的把参数当做结果返回,当然您也可以在这里做复杂的处理后,再返回自己想要的结果(这里的操作是在另一个线程上完成的)
            }
     
            void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                //这时后台线程已经完成,并返回了主线程,所以可以直接使用UI控件了
                this.textBox1.Text = e.Result.ToString();
                //MessageBox.Show(Thread.CurrentThread.ManagedThreadId.ToString());
            }       
        }    
    }

    这种方式只能在异步结束后给控件赋值,
    --即bw_DoWork是异步处理,异步处理过程中不能给控件赋值
    --bw_RunWorkerCompleted方法中可以给控件赋值,可是这个过程不是异步的,如果在bw_RunWorkerCompleted中加上一个System.Threading.Thread.Sleep(3000);画面还是会假死
    3.不使用BackgroundWorker,自己来写线程来实现类似于BackgroundWorker的处理

    子线程给主线程成员赋值的迷惑
    C# code
    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
            // 代码中自己定义的按钮(非显示按钮)
            private Button testBtn = new Button();
     
            private void button1_Click(object sender, EventArgs e)
            {
                Thread thr = new Thread(ControlParent);
                thr.Start();
            }
     
            private void ControlParent()
            {
                Thread.Sleep(3000);
                // 给自己定义的按钮赋值没有问题
                testBtn.Text = "eeee";
                // 给画面上显示的按钮赋值,InvalidOperationException错误(这里迷糊了,子线程不能直接给主线程赋值,那么主线程是什么?)
                this.button1.Text = "asda";// InvalidOperationException!!!!!!!!!!!
            }

    这里的两个按钮,同样是属于一个类,只不过一个显示在画面上,另一个只定义了没有显示,为什么一个赋值成功,另一个就是败了,求大哥大姐们来个破解之法,感激不尽。
    PS:窗体的this.BeginInvoke只能不阻塞后面代码的执行,不能解决画面假死



  • 相关阅读:
    elementui问题汇总
    微信小程序实现微信授权登录
    微信小程序数据存储
    小程序使用第三方服务,需要中转到一个h5页面,返回到指定页面
    小程序开发,通过左上角返回到指定页面
    万恶之源-基本数据类型(list,tuple)
    基础中的基础
    mybatis_plus实现自动填充和逻辑删除
    本地端口占用解决方案
    maven定义版本以来报红解决方案
  • 原文地址:https://www.cnblogs.com/hijushen/p/4239917.html
Copyright © 2020-2023  润新知