c#窗体运行一下然后卡死,无法运行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#窗体运行一下然后卡死,无法运行相关的知识,希望对你有一定的参考价值。

这是一个仪表盘的程序,用两个模块采集信息,然后显示在仪表控件上。但是两个信息采集程序(就是测车速和测转速)同时运行窗体就会卡死,求大神帮忙,不胜感激

namespace WindowsFormsApplication11

public partial class Form1 : Form

。。。

public Form1()

。。。



private void SetPortProperty()


。。。。。


private int i;
private void timer1_Tick_1(object sender, EventArgs e)

double x, b, c;

/////////////// 测 转 速 ////////////////

sp.DiscardInBuffer();
System.Threading.Thread.Sleep(100);
try //读取电压值


bytess[0] = 0x01;
bytess[1] = 0x03;
bytess[2] = 0x00;
bytess[3] = 0x00;
bytess[4] = 0x00;
bytess[5] = 0x01;
bytess[6] = 0x84;
bytess[7] = 0x0A;

sp.Write(bytess, 0, 8);


catch (Exception)

MessageBox.Show("发送数据时发生错误!", "错误提示");
return;

System.Threading.Thread.Sleep(47);

sp.Read(ReceivedDat, 0, 7);

v = ReceivedDat[3];
w = ReceivedDat[4];
x = v * 16 * 16;
c = (x + w) * 6;
b = w;

gaugeContainer1.CircularGauges[0].Pointers[0].Value = c / 1080;

/////////////// 测 车 速 ////////////////

sp.DiscardInBuffer();
System.Threading.Thread.Sleep(10000);
try //读取电压值


bytess[0] = 0x02;
bytess[1] = 0x03;
bytess[2] = 0x00;
bytess[3] = 0x00;
bytess[4] = 0x00;
bytess[5] = 0x01;
bytess[6] = 0x84;
bytess[7] = 0x39;

sp.Write(bytess, 0, 8);


catch (Exception)

MessageBox.Show("发送数据时发生错误!", "错误提示");
return;

System.Threading.Thread.Sleep(47);

sp.Read(ReceivedData, 0, 7);

v = ReceivedData[3];
w = ReceivedData[4];
x = v * 16 * 16;
c = (x + w) * 6;
b = w;

gaugeContainer2.CircularGauges[0].Pointers[0].Value = c / 1080;

你的time1的时间间隔是多少,如果时间很短,然后你又在timer中sleep的话必然会卡死(更别说那个System.Threading.Thread.Sleep(10000);),因为你只有一个线程,这种东西原本适合是用多线程来做的,如果不大改的话,建议将所有的sleep用这个方法来代替代,也就是
public static void Delay(int milliSecond)

int start = Environment.TickCount; while (Math.Abs(Environment.TickCount - start) < milliSecond)//毫秒

Application.DoEvents();


比如原本的Sleep(10000)就是Delay(10000)
至于多线程的方法,简单来说就是新开一个线程,然后将你原本的timer中的代码都放进去,这样它就不会干扰到主界面,不过随之的问题就是其它线程中是不能直接访问主界面的,解决方法你可以搜索下C# 跨线程 控件
参考技术A 你是不是 复制的别人的代码 模块没引用啊!追问

“模块没引用”什么意思

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();
        

这就是一个真正的多线程

参考技术A 我建议你用BackgroundWorker控件比较好,简单易用,我做多线程的时候就常用这个~追问

BackgroundWorker可以实现子线程(后台线程)与主线程的跨线程引用吗?即子线程可以获取其他线程的值吗?

追答

可以~

追问

抱歉,忘了说了,我的第3个线程在运行的同时会将运行的内容不停地显示在主界面的一个text区域,所以主界面上的text区域是在不停地更新的,我使用了BackgroundWorker之后,text任然没有问题,但是主界面还是出现"假死"现象呢!能帮忙再分析下吗?

本回答被提问者采纳

以上是关于c#窗体运行一下然后卡死,无法运行的主要内容,如果未能解决你的问题,请参考以下文章

vs2017写程序时经常卡死,只能结束进程

C# Windows 窗体无法在 Windows10 上加载非托管 C++ DLL

C#中,运行程序时提示:无法直接启动还有类库输出类型的项目?

c# 多线程运行时出现主界面卡死现象如何解决?

eclipse写的窗体在运行时图片能正常显示,打成jar包后无法显示

eclipse运行慢经常卡死,求大神解决