【发布时间】:2023-04-03 00:29:01
【问题描述】:
再次返回另一个串行端口问题。
在过去的两周里,我一直在优化我的代码以尝试读取两个串行设备。目前,该程序获得了几乎所有数据(大约 99% 与我之前的 50% 相比),但我仍然缺少数据。
这是我的“主要”功能:
private Program()
{
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port2.DataReceived += new SerialDataReceivedEventHandler(port2_DataReceived);
port.Open();
port2.Open();
Application.Run();
}
这是我用于两个串行端口的代码:
public void port1IntoBuffer()
{
int messageLength = 96;
byte[] buffer = new byte[messageLength];
port.BaseStream.ReadAsync(buffer, 0, messageLength);
for (int i = 0; i < messageLength; i++)
{
if ((int)buffer[i] <= 48 && (int)buffer[i] > 0)
{
tickQ.Enqueue((new IdDate { Id = (int)buffer[i], Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") }));
}
}
if (!Locked)
{
Locked = true;
Thread readThread = new Thread(() => submitSQL());
readThread.Start();
}
}
我也为端口 2 复制了这段代码。 messageLength 只是用于测试的任意数字。至于我的输入,我期待一个介于 1-48 之间的整数值。 tickQ 变量是一个 ConcurrentQueue,我将两个端口都排入队列(稍后将其出列并发送到 SQL DB)。
如果有人能给我一些关于我做错了什么的提示,我将不胜感激。
谢谢!
编辑1:
阅读BlueStrat的建议后,我将我的sql提交代码更改为以下:
public void submitSQL()
{
lock (Locked)
{
int retryCount = 3;
bool success = false;
while (retryCount > 0 && !success)
{
try
{
IdDate tempData;
using (SqlConnection con = new SqlConnection())
using (SqlCommand cmd = new SqlCommand())
{
con.ConnectionString = "Data Source=xxxxxx;" +
"Initial Catalog=xxxxxx;" +
"User id=xxxxxx; Password=xxxxxx; Connection Timeout=0";
cmd.CommandText = "INSERT INTO XXXXX (submitTime, machineID) VALUES (@submitTIME, @machineId)";
cmd.Connection = con;
con.Open();
while (tickQ.TryDequeue(out tempData))
{
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@machineId", (tempData.Id));
cmd.Parameters.AddWithValue("@submitTIME", tempData.Date);
cmd.ExecuteNonQuery();
}
con.Close();
}
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
retryCount--;
}
finally
{
success = true;
}
}
}
}
现在我的问题是 10 分钟后,我的 RAM 使用量激增(从大约 6MB 增长到 150MB),然后程序崩溃。
编辑 2:在大家的建议下,结果有所改善!昨晚我只错过了大约 15,000 次传输中的 8 次。我将尝试增加我的串行读取缓冲区以希望捕获更多传输。
【问题讨论】:
-
您可以详细说明预期的数据是什么以及您目前得到的数据是什么?
-
我的预期数据是一个介于 1-48 之间的整数值,我记录了收到该值的时间(使用我的 DateTime.Now())。一旦我有两个相同整数值的数据点,我减去到达时间以获得持续时间。我的问题是偶尔会错过过渡,使我的持续时间比应有的长得多。
-
我正在将我的结果与现有系统进行比较(我正在编写的程序将替换它)。我的程序通常读取 5 或 6 次(意思是,旧程序读取 500 次,但我的程序只读取 495 次)。我会尝试从这个旧的 VB 程序中复制代码,但它使用的是 MSCommLib,我真的不想使用它。
-
这可能是,我会尝试缩小我的缓冲区大小。令人讨厌的是,我通常要等几个小时后才能判断我所做的更改是否有效(因为丢失的数据是如此不一致和罕见)。可悲的是,这个串行设备只传输数字,没有分隔字符或任何东西。
-
啊,这是个好主意。我将尝试进行测试。感谢您迄今为止的帮助!
标签: c# multithreading serial-port