insert 插入資料有丟包,感覺是執行緒阻塞的問題,求正確的異步寫法
private void button1_Click(object sender, EventArgs e)
{
try
{
//初始化串口引數
InitSerialPortParameter();
master = ModbusSerialMaster.CreateRtu(port);
ExecuteFunction();
}
catch (Exception)
{
MessageBox.Show("初始化例外");
}
}
private async void ExecuteFunction()
{
String connetStr = "server=10.10.20.5;port=3309;user=root;password=rootqsr; database=db_qualitymanager;";
MySqlConnection conn = new MySqlConnection(connetStr);
try
{
if (port.IsOpen == false)
{
port.Open();
}
if (functionCode != null)
{
switch (functionCode)
{
case "01 Read Coils"://讀取單個線圈
//讀取線圈
slaveAddress = byte.Parse("1");
startAddress = ushort.Parse("0");
numberOfPoints = ushort.Parse("20");
coilsBuffer = master.ReadCoils(slaveAddress, startAddress, numberOfPoints);
for (int i = 0; i < coilsBuffer.Length; i++)
{
bool m = coilsBuffer[i];//線圈狀態
if (m == true)
#region
{
//讀取暫存器
int j = i * 4 + 6;
startAddress1 = ushort.Parse(j+"");
numberOfPoints1 = ushort.Parse("3");
registerBuffer = master.ReadHoldingRegisters(slaveAddress, startAddress1, numberOfPoints1);
string x = registerBuffer[0] + "";
string y = registerBuffer[2] + "";
if(x == "0")
{
continue;
}
else
{
if (i < 10)
{
string dpr = "z_0" + i;
conn.Open();
string today = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string sql = string.Format("insert into "+ dpr +"(vultime,opetime,prdate) values ('{0}','{1}','{2}')", x, y, today);
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.ExecuteNonQuery();
conn.Close();
//修改暫存器
string s = j + "";
startAddress = ushort.Parse(s);
string[] strarr = { "0" };
registerBuffer[0] = ushort.Parse(strarr[0]);
await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
}
else
{
string dpr = "z_" + i;
conn.Open();
string today = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string sql = string.Format("insert into " + dpr + " (vultime,opetime,prdate) values ('{0}','{1}','{2}')", x, y, today);
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.ExecuteNonQuery();
conn.Close();
//修改暫存器
string s = j + "";
startAddress = ushort.Parse(s);
string[] strarr = { "0" };
registerBuffer[0] = ushort.Parse(strarr[0]);
await master.WriteSingleRegisterAsync(slaveAddress, startAddress, registerBuffer[0]);
}
}
#endregion
}
//SetMsg(coilsBuffer[i] + " ");
}
//SetMsg("\r\n");
break;
}
}
else
{
MessageBox.Show("請選擇功能碼!");
}
port.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
uj5u.com熱心網友回復:
1 要么別用異步。2 既然用了異步,那button也要異步。
不要同步異步混用。容易死鎖。
uj5u.com熱心網友回復:
實在看不出你哪里異步,再說,代碼是這么寫的么?業務分離,單一原則,兄弟uj5u.com熱心網友回復:
而且mysql插入資料,不可能有丟包哈。uj5u.com熱心網友回復:
怎么說呢,我沒有系統地學習過C#,就看過一個簡單的家庭理財軟體視頻,不講基礎直接開干的那種,所以很多東西也不明白,現在自學python,對這個也不想深究了,只要能實作功能就好,一般都是簡單的需求。
回到正題,我對這個程式做了三秒鐘點擊一次button1的定時器,去獲取PLC中的資料,如果PLC我只連幾個點,SQL插入資料是正常的,接的點多了就會丟失,想著大概是因為3秒鐘不夠執行完for回圈里面的內容,所以查到可以用異步,但不會用。
uj5u.com熱心網友回復:
我看了個簡單的異步例子,懂,但是不知道怎么用到我這個實際的需求上···
uj5u.com熱心網友回復:
Button里執行Task.Run,資料庫操作部分不要用全域變數。uj5u.com熱心網友回復:
簡單的異步 樓主 可以了解一下 backgroundWorker C# 這個控制元件 很簡單的異步uj5u.com熱心網友回復:
需要控并發。串口只有一個。至于你說啥丟包,我們只能說丟包到不至于,只是無法保證順序。
比如你點擊3次,那么就是3個task同時在爭搶串口操作,系統可以保證你這3個task都可以執行完畢,但不保證3個task的對串口的操作的執行順序
uj5u.com熱心網友回復:
在你弄不清同步/異步、并行/并發的情況下,別動手不然那種代碼看不得,看著很高級,其實全是坑。
uj5u.com熱心網友回復:
https://download.csdn.net/download/nebuung/12928267包在這里,請大佬指點一下,實在木有辦法了
程式運行的結果是這樣子的,除了z08的資料完整外,其他都是缺失的,請教程式怎么改才會避免這種丟失的情況(PS:感應器的通電時間和斷開時間之和在5分鐘左右)

uj5u.com熱心網友回復:
你上的圖已經說明問題了。因為每3秒做一次,多次并行會形成并發爭搶共享資源“串口”,造成執行順序混亂,同時當越來越多的task插隊,混亂也會越來越嚴重。
所以問題是“有人插隊”,自然解決的手段就是排隊
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/172979.html
標籤:C#
