讀串口的程序死掉,有打計數器,計數器在20-30分鐘不等會停止跳動。
一開始懷疑是GC回收了Timer,使用了保活,不行;
後來懷疑系統回收了中間變量,使用了微軟的TryStartNoGCRegion,
不行;
不接串口時,計數器單獨放一個晚上都沒事;
串口使用C語言讀取,2個小時沒事。
讀串口的部分查閱了微軟標準的寫法,讀寫的buffer每次都是有清除的。
請大神指點,放久了,為何Timer計數會死掉。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using MES.Util;
using System.Runtime;
namespace MES.Operation
{
public partial class Suckion : Form
{
[System.Security.SecurityCritical]
public static bool TryStartNoGCRegion;
public static SerialPort serialPort = null;
public Suckion()
{
InitializeComponent();
}
public static string[] SerialPortNames
{
get
{
string[] serialports = SerialPort.GetPortNames();
Array.Sort(serialports, new Comparison<string>(
delegate (string x, string y)
{
if (x.Length > 3 && y.Length > 3)
{
string index1 = x.Substring(3);
string index2 = y.Substring(3);
try
{
int n1 = Convert.ToInt32(index1);
int n2 = Convert.ToInt32(index2);
return n1 - n2;
}
catch
{
}
}
return 0;
}));
return serialports;
}
}
System.Timers.Timer t = new System.Timers.Timer(1500);
private void Suckion_Load(object sender, EventArgs e)
{
//comboBox1.Items.AddRange(SerialPortNames);
//comboBox1.SelectedIndex = 0;
label5.Text = Util.PublicVar.UserID;
label3.Text = Util.PublicVar.Line;
//打開串口
serialPort = new SerialPort();
serialPort.PortName = "COM1";
serialPort.BaudRate = Convert.ToInt32(9600);
serialPort.Parity = Parity.None;
serialPort.DataBits = Convert.ToInt32(8);
serialPort.StopBits = StopBits.One;
serialPort.Handshake = Handshake.None;
serialPort.WriteTimeout = 200;
serialPort.ReadTimeout = 200;
if (serialPort.IsOpen == false)
{
serialPort.Open();
}
Query();
//異步線程定時器
t.Elapsed += new System.Timers.ElapsedEventHandler(GetSuctionValue);//到达时间的时候执行事件;
t.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
//GC.KeepAlive(t);
}
private void Query()
{
string sql = @"SELECT TOP 50
bi.Line 產線
,bi.Main 主機
,bi.SuctionValue 吸力
,case when bi.SuctionValue is null then '' when bi.SuctionValue<-7 and bi.SuctionValue>-15 then 'OK'
else 'NG' end 判定結果
,CONVERT(varchar(100), bi.SuctionTime, 20) 吸力上傳時間
FROM dbo.BindingInfo bi WHERE bi.Line='" + Util.PublicVar.Line + "' and bi.SuctionTime is not null ORDER BY bi.SuctionTime desc";
dataGridView1.DataSource = Util.SQLHelper.GetDataTable(sql);
for (int i = 0; i < dataGridView1.RowCount; i++)
{
if (dataGridView1.Rows[i].Cells["判定結果"].Value.ToString() == "NG")
{
dataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Red;
}
}
}
void GetSuctionValue(object source, System.Timers.ElapsedEventArgs e)
{
try
{
this.BeginInvoke(new TextOption(F));//invok 委托实现跨线程的调用
GC.KeepAlive(t);
}
catch(Exception ex)
{
File.AppendAllText(@"C:/Test.txt",ex.ToString());
}
}
delegate void TextOption();//定义一个委托
private void F()
{
try
{
label8.Text = (int.Parse(label8.Text) + 1).ToString();
serialPort.DiscardInBuffer();
byte[] b = new byte[] { 01, 03, 00, 00, 00, 02, 0xC4, 0x0B };
serialPort.Write(b, 0, 8);
}
catch (Exception)
{
}
SerialPort sp = serialPort;
sp.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
}
private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//开辟接收缓冲区
byte[] ReDatas = new byte[serialPort.BytesToRead];
//从串口读取数据
serialPort.Read(ReDatas, 0, ReDatas.Length);
//实现数据的解码与显示
AddData(ReDatas);
serialPort.DiscardOutBuffer();
}
/// <summary>
/// 解码过程
/// </summary>
/// <param name="data">串口通信的数据编码方式因串口而异,需要查询串口相关信息以获取</param>
public void AddData(byte[] data)
{
Thread.Sleep(1000);
if (data.Length != 9)
{
return;
}
if (data[0].ToString() != "1")
{
return;
}
StringBuilder sb = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
byte[] b2 = new byte[4];
sb.Clear();
sb.AppendFormat("{0:x2}", data[3]);
sb.AppendFormat("{0:x2}", data[4]);
uint num = uint.Parse(sb.ToString(), System.Globalization.NumberStyles.AllowHexSpecifier);
byte[] floatValue = BitConverter.GetBytes(num);
int value = BitConverter.ToInt16(floatValue,0);
try
{
label2.BeginInvoke(new Action(
() =>
{
if (value.ToString().Length < 5)
{
label2.Text = ((value * 0.1).ToString("0.0"));
}
}
)
);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
throw;
}
}
private void ResultDisplay(string ResultString, Color color)
{
if (Result_1.Visible == true && Result_2.Visible == true)
{
Result_1.Text = ResultString;
Result_1.ForeColor = color;
Result_2.Visible = false;
Result_2.Text = "";
}
else if (Result_1.Visible == true && Result_2.Visible == false)
{
Result_1.Visible = false;
Result_1.Text = "";
Result_2.Visible = true;
Result_2.Text = ResultString;
Result_2.ForeColor = color;
}
else if (Result_1.Visible == false && Result_2.Visible == true)
{
Result_2.Visible = false;
Result_2.Text = "";
Result_1.Visible = true;
Result_1.Text = ResultString;
Result_1.ForeColor = color;
}
}
private void button1_Click(object sender, EventArgs e)
{
//綁定
string sql = "UPDATE dbo.BindingInfo SET SuctionValue = '" + label2.Text.Trim() + @"',SuctionTime=getdate()
WHERE Main = N'" + Main.Text.Trim() + "' and Line='" + Util.PublicVar.Line + "'";
if (Util.SQLHelper.ExecuteNonQuery(sql) > 0)
{
ResultDisplay("已上傳", Color.Black);
}
else
{
ResultDisplay("未上傳", Color.Red);
}
Main.Text = "";
Main.Focus();
Query();
}
private void Main_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
F();
//檢查主機唯一性
string sql = "select count(ID) from dbo.BindingInfo where Main=N'" + Main.Text.Trim() + "'";
if ((int)Util.SQLHelper.ExecuteScalar(sql) == 0)
{
ResultDisplay("主機未掃碼", Color.Red);
Main.Text = "";
Main.Focus();
return;
}
sql = "select count(ID) from dbo.BindingInfo where Main=N'" + Main.Text.Trim() + "' and DiPa is null";
if ((int)Util.SQLHelper.ExecuteScalar(sql) >= 1)
{
ResultDisplay("地扒未掃碼", Color.Red);
Main.Text = "";
Main.Focus();
return;
}
////檢查吸力工序是否有做
//sql = "select count(ID) from dbo.BindingInfo where Main=N'" + Main.Text.Trim() + "' and SuctionValue is not null";
//if ((int)Util.SQLHelper.ExecuteScalar(sql) >= 1)
//{
// ResultDisplay("吸力已測試", Color.Red);
// Main.Text = "";
// Main.Focus();
// return;
//}
//ResultDisplay("主機OK", Color.Black);
////Main.Focus();
sql = "UPDATE dbo.BindingInfo SET SuctionValue = '" + label2.Text.Trim() + @"',SuctionTime=getdate()
WHERE Main = N'" + Main.Text.Trim() + "' and Line='" + Util.PublicVar.Line + "'";
if (Util.SQLHelper.ExecuteNonQuery(sql) > 0)
{
ResultDisplay("已上傳", Color.Black);
}
else
{
ResultDisplay("未上傳", Color.Red);
}
Main.Text = "";
Main.Focus();
Query();
}
}
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
/// <summary>
/// 释放内存
/// </summary>
public static void ClearMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
[System.Security.SecurityCritical]
public static void EndNoGCRegion()
{
if (GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
GC.EndNoGCRegion();
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}