SUPER_CRJ 发表于 2020-6-3 12:07:16

C#写软件如何重新开一个线程用于更新界面

本人C#自学,大神轻拍。

最近做一个与STM32进行USB通信的C#软件,数据量32KB/S左右。
最后要在:上位机软件进行显示(C#,使用DataGridView控制显示)。
网上看:最好建立一个线程用于USB通信,一个线程用于DataGridView控件的显示。

所以请教:
1:如何建立?(这个我可以自己搜索)
2:有没有什么要注意的坑?
3:界面如果刷新比较快,怎么样才能不卡?(之前做的一个界面就比较卡,不过没有开线程。因为不会开!)

bbandpp 发表于 2020-6-3 12:19:15

也是自学,所有都是百度就可以

68336016 发表于 2020-6-3 12:25:35

没用过C#,只用过VC。
主线程负责界面这些,开辟子线程干计算这些耗时的,这样不会阻塞界面线程(主线程),避免让人看起来卡顿。
子线程通过线程间通信,将一些数据发给界面的主线程,这样界面就刷新了。

hushaoxin 发表于 2020-6-3 12:31:56

更新界面只能在主线程做,你可以开一个线程吧需要计算的,遍历数据的,访问数据库的等等操作都做好,然后通过消息队列发送给主线程,主线程就是界面的那个线程,他收到消息后,根据内容再更新界面。
当然还有委托啊等方式,个人觉得不太适合假面比较复杂的时候,麻烦,还是喜欢消息队列

hcambridge 发表于 2020-6-3 12:57:05

可以用简单的线程方式,百度下backgroundworker,然后用backgroundworker建立线程处理耗时的线程,界面只在主线程刷新。

4058665 发表于 2020-6-3 13:53:32

创建任务
new Thread((ThreadStart)delegate { UpdateControls(); }).Start();

//更新控件任务
void UpdateControls(){
    while (!BoolExit){
      BeginInvoke((Action)delegate{
            //更新控件你的控件数据赋值区
            //.....
      });
      Thread.Sleep(100);      //根据需要
    }
}

卡的原因是UI线程是默认线程更新一些控件会比较耗资源,这需要创建任务,在新任务中使用委托更新
USB任务也类似
在整个系统退出后,任务也要退出   用BoolExit的原因

sleet1986 发表于 2020-6-3 13:55:36

更新只能在主线程做的,耗时的在其他线程做完,主界面不做耗时操作,就不会卡的。

chenchaoting 发表于 2020-6-3 14:33:46

hushaoxin 发表于 2020-6-3 12:31
更新界面只能在主线程做,你可以开一个线程吧需要计算的,遍历数据的,访问数据库的等等操作都做好,然后通 ...

有没有合适的消息队列可以用?

7073640 发表于 2020-6-3 16:53:47

界面是委托回掉跨线程

jarodzz 发表于 2020-6-4 00:53:01

資料顯示更新可以用data binding。

yuyu87 发表于 2020-6-4 08:30:44

1.开个共享用的变量 2.frm.invoke委托

hy317 发表于 2020-6-4 09:04:30

list<struct **>

justdomyself 发表于 2020-6-4 09:04:41

用委托…

makesoft 发表于 2020-6-4 09:08:24

C#这种应用到底哪种是正统的做法,俺以前也是用委托,感觉不理想。

zyqcome 发表于 2020-6-4 11:57:18

本帖最后由 zyqcome 于 2020-6-4 12:00 编辑

data binding 是wpf 框架,确实可以省很多事,可以绑定到动态链表,如果有大量的数据处理,可以单开task,然后事件回调,或者异步等待,要是有疯狂的写入到界面,可以试一试分页显示。要是希望界面疯狂的滚动,winform,有一种dataview开动态共享模式(大概是单元格共享复用的模式)可以看着啪啪啪的往里写,wpf我没测试过非常大量的数据一次加载

adswads 发表于 2020-6-4 13:34:31

本帖最后由 adswads 于 2020-6-4 13:35 编辑

好一点的数据绑定,直接改数据源,至于卡不卡,得得实际测试,你这个数据量一般不会卡
当然不卡的前提是单独开个线程接收数据,开线程很简单了。如果是绑定的,就不用每次赋值了
下面是比较明了的写法(wpf .net4.5或以上)
Task.Run(() =>
            {
                //数据接收代码

                Dispatcher.Invoke(() =>
                {
                  //界面控件赋值代码
                });
            });

页: [1]
查看完整版本: C#写软件如何重新开一个线程用于更新界面