本帖最后由 zy_6084 于 2013-07-17 09:36:53 编辑

解决方案 »

  1.   

    没做过WPF的,根据楼主的描述,会不会是点下按钮的时候,正好在读取串口了,但是被强制终止,所以才发生此错误?楼主看下错误发生的地方以及Exception的类型,看下该异常的解释
      

  2.   

    感谢楼上的解答。我的错误一般发生在我定义的事件接收标志位上。一般主画面上一到读取这个值做逻辑判断,就死到那了,连错误都不报。那我能不能加个当写入按钮触发时,如果正在接收数据,这时等待一段时间。等到接收事件完成后(此处再用一个接收事件完成的标志位),再写入数据?还是我直接把接收事件用LOCK语句包起来,这样是否也能达到类似效果?
      

  3.   

    部分代码如下,全部代码比较长
    //接受串口数据
            public void myserialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                try
                {
                    receiving = true; //接收事件标志位
                    readData = new byte[myserialport.BytesToRead];
                    myserialport.Read(readData, 0, readData.Length);
                    myserialport.DiscardOutBuffer();
                    string tempstr;
                    tempstr = Convert.ToString(readData[0], 16);
                    switch (funcode)//更改接收事件触发的阀值
                    {
                        case "读取":
                            myserialport.ReceivedBytesThreshold = 28;
                            break;
                        case "写入":
                            myserialport.ReceivedBytesThreshold = 24;
                            break;
                        case "停止":
                            myserialport.ReceivedBytesThreshold = 22;
                            break;
                        case "运行":
                            myserialport.ReceivedBytesThreshold = 22;
                            break;
                    }
                    if (tempstr.ToUpper() == "E5")//PLC第一次返回数值正确,PC再次发送命令给PLC
                    {
                        byte[] arrayResend1 = new byte[6];
                        arrayResend1[0] = 0x10;
                        arrayResend1[1] = 0x02;
                        arrayResend1[2] = 0x00;
                        arrayResend1[3] = 0x5C;
                        arrayResend1[4] = 0x5E;
                        arrayResend1[5] = 0x16;
                        Thread.Sleep(50);
                        myserialport.Write(arrayResend1, 0, 6);
                    }
                    else if (tempstr.ToUpper() != "")//如果PC第一次发给PLC值正确,PLC第一次返回必为E5,然后再次发送命令,此时PLC二次返回必不会是E5,所以此时触发显示事件
                    {
                        receiving=false;
                        OnDisplay(new EventArgs());//自定义的主界面显示事件触发方法
                    }
                }
                //catch (Exception err)
                //{   
                //    errcode=err.Message;
                //    OnChilderror(new EventArgs());
                //}
                catch (Exception err)
                { 
                    errcode=err.Message;
                }
                
            }
    //写入按钮事件
          private void btnstart_Click(object sender, RoutedEventArgs e)
            {
                
                try
                {
                    timer.Stop();//停止计时器
                    txtpos.Text = "";
                    txtdis1.Text = "";
                    while (writeflag == true)//写入数据方法的标志位
                    {
                        if (ppidll.Receiving == false)
                        {                        if (word1 && word2)//判断两次写入成功的标志
                            {
                                writeflag = false;
                                word1 = false;
                                word2 = false;
                            }
                            if (ppidll.Flag1 == false && ppidll.Sign3 == true)
                            {
                                ppidll.WritePPIWord("04", "01", "01", "84", "000096", "10", "1000");
                            }                        if (ppidll.Flag1 == false && ppidll.Sign4 == true)
                            {
                                ppidll.WritePPIWord("04", "01", "01", "84", "000160", "10", "5000");
                            }                    }
                        if (ppidll.Receiving == true)
                        {
                            ppidll.Receiving = false;
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    timer.Start();
                }
            }
      

  4.   

    1.界面卡死最终本质原因是 widnows消息得不到及时处理
    2.发生1的原因有两个:
      1)UI线程阻塞,可能是你程序写得有问题,比如执行耗时操作,也可能UI线程和其他子线程发生死锁
      2)子线程占用CPU控制权太频繁,造成UI线程得不到足够CPU时间片,也就是UI线程经常被挂起
    3.贴代码 看得清楚  不然没人懂  就像上面1、2感觉不接地气
      

  5.   

    数据接收和写入没必要分开  可以同时进行  不知道你timer干啥用
    while (writeflag == true)//写入数据方法的标志位
    这个条件有可能一直未true吗  如果是 界面卡死必然
      

  6.   

    我写定时器因为需要实时读取PLC中的部分值做显示。wirteflag在PLC二次返回数据时执行界面更新时变为FALSE,再次执行写入方法时TRUE