c#非委托方式在子线程里操作UI控件(实际上运算逻辑在子线程,更新还是在主线程,解决了UI界面无响应的问题)

1. 创建一个全局变量标识线程是否执行完毕,创建一个或多个全局变量用于对应线程执行中的各种逻辑情况


2. 在触发事件中创建线程,并执行,在执行末端,更改上面定义的全局变量。并根据线程中的执行情况改变其他全局变量的值。


3. 创建一个定时器,每隔一个时间间隔就判断一下,这个全局变量是否已经改变,如果改变说明线程执行完毕。
    然后在线程执行完毕的情况下,根据其他变量的值进行相应的ui操作


4,这是最重要的一点,当线程执行完后,一定一定一定要将线程是否执行完毕的标识变量进行重置!!!以免再次执行时线程一开起才运行下就直接结束了。

   【我做的是就不注意忽略了这一点,导致浪费整整几个小时找原因】

 

关键代码:获取1到10之间所有不重复的七位数组合,运算放在子线程,运算完后在定时器里面根据结果跟新UI控件

(为了大家好理解,只给了关键代码,想要全部代码的在评论了给我说就行了,我的很多问题都是靠CSDN解决的,原意为他的CSDN的繁荣尽一份力)



        static StringBuilder result = new StringBuilder();  //用来承载所有数据
        string[] i_j = new string[7];
        long num = 0;  //选出来的数的总个数
        LoadFrom load;//加载框窗体
        Thread thread;//进行运算工作的子线程
        static int log = 0; //线程运行结束标志

        private void btnChaXun_Click(object sender, EventArgs e)  //运算方法
        {
            timer1.Enabled = true; //开启定时器


            num = 0;//总数重置
            rTBShow.Text = "";//结果重置
            result = new StringBuilder();
         //   result.Clear();//中转数据集重置
            lab_start.Text = "开始时间:" + DateTime.Now.ToString();//重置时间
            lab_end.Text = "终止时间:计算中......";


            thread = new Thread(new ThreadStart(query)); //开启线程
            thread.Start();


            load = new LoadFrom();
            load.ShowDialog();
           
         }
 //================底层的最直接的实现运算的线程方法=====================================       
        public void query()
        {
            for (int i1 = 1; i1 <= 10; i1++)
                for (int i2 = 1; i2 <= 10; i2++)
                    for (int i3 = 1; i3 <= 10; i3++)
                        for (int i4 = 1; i4 <= 10; i4++)
                            for (int i5 = 1; i5 <= 10; i5++)
                                for (int i6 = 1; i6 <= 10; i6++)
                                    for (int i7 = 1; i7 <= 10; i7++)
                                    {
                                        //-----------------------------------------------排出7个数(升序冒泡排序)-------------------------------------------------------------------
                                        //将i1到i7进行排序,并将排序结果存入一数组当中
                                        int[] up = new int[7] { i1, i2, i3, i4, i5, i6, i7 };
                                        Array.Sort(up);   //对着up进行升序排序
                                        //---------------------------------------1. 7个数中不能有重复的-----------------------------------------------------------------------------------------
                                        if (zl1_7个数不能重复.Checked)
                                        {
                                            if (!(up.Distinct().Count() == up.Length)) continue; //排除7个数中含有相同数的情况
                                        }     
                                        //-------------------------------------------------------------
                                        result.Append(i1 + "" + i2 + "" + i3 + "" + i3 + "" + i5 + "" + i6 + "" + i7 + "\n\n");
                                        num++;
                                    }


            log = 1;  //表示关掉加载框
            thread.Abort();
        }


        private void timer1_Tick(object sender, EventArgs e)  //根据子线程结果,在定时器里执行UI操作
        {
            if (log == 1)
            {
                timer1.Enabled = false;  //线程运行结束了,关闭定时器不在监听线程运行
                rTBShow.Text = result.ToString();  //将线程运行的结果赋值给ui控件
                load.Close(); //关掉正在加载的提示框
                result.Clear();//临时数据容器集重置
                lab_end.Text = "终止时间:" + DateTime.Now.ToString();
              MessageBox.Show("程序运算完毕,共有 " + num + " 个符合要求的7位数.", "温馨提示:");
                log = 0;
            }
        }
//----------------------------------------------------------------------------------------------------------------
    }
}

 

这个方法特点:在子线程运算时,UI线程可以自由操控,然后在定时器里面给UI线程赋值时,如果只是百万级的数据写入,UI线程也可以自由操控,如果是千万级的,会出现轻微的不响应问题,,,,(不过这个感觉无法避免,毕竟就算用委托,也不过是子线程委托UI线程进行操作UI控件,最终执行的还是UI线程,而只要UI控件被操作,且是千万级的数据写入操作,那么这个UI控件所在的UI线程肯定会有一定的阻塞无响应情况)

 

如果这篇文章对您有用的话,可以点击右边的打赏赞助下哦^_^

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值