首先介绍一下项目:
项目是在一台win7 32位系统的电子秤上开发的。功能是现实,从数据库中读取商品的价格,然后用C#代码读出com口的重量数据,计算出价格,并打印出来。
错误界面如下,每当用了1个小时左右,点击取商品的重量就报错。如下图:
然后代码如下:
1、声明的变量
SerialPort serialPort1 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); //初始化串口设置
public delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
public Displaydelegate disp_delegate;
private bool Listening = false;//是否没有执行完invoke相关操作
private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
private static int nums = 0;
private string lyzf;
private static int kaiguan = 1;
2、点击item的代码
//点击item
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
if(kaiguan==1)
{
kaiguan = 0;
try
{
Closing = true;
while (Listening) Application.DoEvents();
//打开时点击,则关闭串口
serialPort1.Close();
Closing = false;
}
catch
{
serialPort1 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
//关闭并口时发生异常,不用再次打开
}
//System.Threading.Thread.Sleep(100);
decimal zl = 0.0m;
Decimal.TryParse(label5.Text, out zl);
if (zl>0&&zl < 10)
{
ListViewHitTestInfo info = listView1.HitTest(e.X, e.Y);
if (info.Item != null)
{
Frm_QueRen f3 = new Frm_QueRen(info.Item.SubItems[1].Text.ToString(), info.Item.SubItems[2].Text.ToString(), info.Item.SubItems[3].Text.ToString(), info.Item.SubItems[4].Text.ToString(), info.Item.SubItems[5].Text.ToString(), info.Item.SubItems[6].Text.ToString(), zl, label11.Text, info.Item.SubItems[7].Text.ToString(), info.Item.SubItems[8].Text.ToString());
f3.ChangeEvent += new ChangeHandel(your_event);
f3.ShowDialog();
}
}
else
{
//重量取得不准确执行这里
try
{
serialPort1.Open();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
}
catch (Exception ex)
{
//捕获到异常信息,创建一个新的comm对象,之前的不能用了。
serialPort1 = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
//现实异常信息给客户。
serialPort1.Open();
serialPort1.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
Closing = false;
}
}
kaiguan = 1;
}
}
3、取重量的代码。
void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Closing) return;
try
{
if (serialPort1.IsOpen)
{
Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
Byte[] InputBuf = new Byte[128000];
serialPort1.Read(InputBuf, 0, serialPort1.BytesToRead); //读取缓冲区的数据直到“}”即0x7D为结束符
//InputBuf = UnicodeEncoding.Default.GetBytes(strRD); //将得到的数据转换成byte的格式
//1.缓存数据
// this.Invoke(disp_delegate, InputBuf);
this.Invoke((EventHandler)(delegate
{
//追加的形式添加到文本框末端,并滚动到最后。
//lyzf=lyzf+ Encoding.ASCII.GetString(InputBuf);
ASCIIEncoding encoding = new ASCIIEncoding();
lyzf = lyzf + encoding.GetString(InputBuf);
//lyzf = lyzf.Substring(lyzf.Length - 30);
if (lyzf.Length >= 60)
{
if (lyzf.Contains("S") && lyzf.Contains("kg"))
{
if (Regex.IsMatch(lyzf, "[0-9.]+"))
{
MatchCollection s1 = Regex.Matches(lyzf, "[0-9.]+");
string[] strs = new string[s1.Count];
for (int i = 0; i < s1.Count; i++)
{
strs[i] = s1[i].Value;
}
string zhi = "0";
if (s1.Count >= 3)
{
if (strs[s1.Count - 1] == strs[s1.Count - 2])
{
zhi = strs[s1.Count - 1];
double d1 = 0.0;
Double.TryParse(zhi, out d1);
zhi = Math.Round(d1, 2).ToString();
label5.Text = zhi;
//System.Threading.Thread.Sleep(100);
lyzf = "";
}
else if (strs[s1.Count - 1] == strs[s1.Count - 3])
{
zhi = strs[s1.Count - 3];
double d1 = 0.0;
Double.TryParse(zhi, out d1);
zhi = Math.Round(d1, 2).ToString();
label5.Text = zhi;
//System.Threading.Thread.Sleep(100);
lyzf = "";
}
else if (strs[s1.Count - 2] == strs[s1.Count - 3])
{
zhi = strs[s1.Count - 3];
double d1 = 0.0;
Double.TryParse(zhi, out d1);
zhi = Math.Round(d1, 2).ToString();
label5.Text = zhi;
//System.Threading.Thread.Sleep(100);
lyzf = "";
}
}
}
}
System.Threading.Thread.Sleep(100);
}
})
);
}
}
catch (Exception ex) //超时处理
{
}
finally
{
Listening = false;//我用完了,ui可以关闭串口了。
}
}
4、错误日志
日志名称: Application
来源: .NET Runtime
日期: 2019/4/29 星期一 下午 4:35:54
事件 ID: 1026
任务类别: 无
级别: 错误
关键字: 经典
用户: 暂缺
计算机: MS-20180622QCSF
描述:
Application: ChengZhong.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
at System.IO.Ports.SerialPort.get_BytesToRead()
at ChengZhong.Frm_ChengZhong.Comm_DataReceived(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialDataReceivedEventHandler.Invoke(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialPort.CatchReceivedEvents(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialStream+EventLoopRunner.CallReceiveEvents(System.Object)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
事件 Xml:
Application: ChengZhong.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
at System.IO.Ports.SerialPort.get_BytesToRead()
at ChengZhong.Frm_ChengZhong.Comm_DataReceived(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialDataReceivedEventHandler.Invoke(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialPort.CatchReceivedEvents(System.Object, System.IO.Ports.SerialDataReceivedEventArgs)
at System.IO.Ports.SerialStream+EventLoopRunner.CallReceiveEvents(System.Object)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()