c# 多线程运行时出现主界面卡死现象如何解决?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 多线程运行时出现主界面卡死现象如何解决?相关的知识,希望对你有一定的参考价值。
我在主界面上用了3个timer,一个不停更新显示当前时间,一个滚动显示进度条,最后一个为一个进程,用来处理其他事务,如数据库的增删改查等,在3个线程同时开启时会出现主界面的“假死”现象,我尝试过将timer改为Thread,但是提示我不可以跨线程调用,加了将Thread加了委托之后可以实现跨线程了,但是还是会出现“假死”,求各位大哥指教一下小弟。之前学过几年Java,c#刚学,求大神们指点一下,多谢了!没有悬赏分了,抱歉!
无论是哪种语言都一样,控件是主线程在运行的,你创建新的线程去跨线程访问就会冲突,在一个线程里处理一个事情,另一个线程被忽略,肯定会假死。举个例子,用C#,我拖放一个richtextbox记录事件,一个button触发事件开始,一个label记录进度,一个progressBar显示进度。
//线程工作private void even()
invor("准备就绪\\r\\n", 0, eventpe.sta);
Thread.Sleep(500);
invor("通道1数据采集完毕......." + DateTime.UtcNow.ToLocalTime().ToLongTimeString() + "\\r\\n", 20,eventpe.doev);
Thread.Sleep(2000);
invor("通道2数据采集完毕......." + DateTime.UtcNow.ToLocalTime().ToLongTimeString() + "\\r\\n", 40, eventpe.doev);
Thread.Sleep(3000);
invor("通道3数据采集完毕......." + DateTime.UtcNow.ToLocalTime().ToLongTimeString() + "\\r\\n", 70, eventpe.doev);
Thread.Sleep(500);
invor("通道4数据请求失败......." + DateTime.UtcNow.ToLocalTime().ToLongTimeString() + "\\r\\n", 75, eventpe.doev);
Thread.Sleep(2000);
invor("通道5数据采集完毕......." + DateTime.UtcNow.ToLocalTime().ToLongTimeString() + "\\r\\n", 95, eventpe.doev);
Thread.Sleep(2000);
invor("数据比对分析中...\\r\\n", 98, eventpe.doev);
Thread.Sleep(500);
invor("Done!", 100, eventpe.end);
//枚举线程状态
enum eventpe
sta,doev,end
//委托主线程控件方法
void invor(string sg,int va,eventpe ik)
switch(ik)
case eventpe.sta:
richTextBox1.BeginInvoke(new EventHandler(delegate
richTextBox1.Text = sg;
));
progressBar1.BeginInvoke(new EventHandler(delegate
progressBar1.Visible = true;
progressBar1.Value = 0;
));
label1.BeginInvoke(new EventHandler(delegate
label1.Visible = true;
label1.Text = "0%";
));
break;
case eventpe.doev:
progressBar1.BeginInvoke(new EventHandler(delegate
progressBar1.Value = va;
));
label1.BeginInvoke(new EventHandler(delegate
label1.Text = va.ToString() + "%";
));
richTextBox1.BeginInvoke(new EventHandler(delegate
richTextBox1.Text += sg;
));
break;
case eventpe.end:
progressBar1.BeginInvoke(new EventHandler(delegate
progressBar1.Visible =false;
));
label1.BeginInvoke(new EventHandler(delegate
label1.Visible =false;
));
break;
//初始化按钮事件和状态
public void btn_event()
//初始化
progressBar1.Visible = false;
label1.Visible = false;
//按钮事件
btn.Click += (object sen, EventArgs ed) =>
Thread.Sleep(500);
Thread th = new Thread(even);
th.Start();
;
在程序中直接加入初始化就好了
public Form1()InitializeComponent();
btn_event();
这就是一个真正的多线程
BackgroundWorker可以实现子线程(后台线程)与主线程的跨线程引用吗?即子线程可以获取其他线程的值吗?
追答可以~
追问抱歉,忘了说了,我的第3个线程在运行的同时会将运行的内容不停地显示在主界面的一个text区域,所以主界面上的text区域是在不停地更新的,我使用了BackgroundWorker之后,text任然没有问题,但是主界面还是出现"假死"现象呢!能帮忙再分析下吗?
本回答被提问者采纳以上是关于c# 多线程运行时出现主界面卡死现象如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
梦幻西游无法运行,每次运行都是到更新完之后进入主界面时出现程序“卡死”现象。
C# 耗时的程序 界面卡死,如何做一个缓冲界面,例如有个圆圈在旋转的效果展示