【发布时间】:2021-06-12 20:35:47
【问题描述】:
我有一个来自供应商的演示应用程序。这个演示应用程序允许我通过网络连接连接到 RFID 阅读器。一旦建立连接,我就可以扫描 RFID 标签,然后标签数据会显示在应用程序上。
每当 CALienServer 收到来自 RFID 阅读器的消息时,都会引发事件处理程序。
private void addServerEvents(int idx)
{
mServers[idx].ServerMessageReceived += new CAlienServer.ServerMessageReceivedEventHandler(mServer_ServerMessageReceived);
mServers[idx].ServerConnectionEstablished += new CAlienServer.ServerConnectionEstablishedEventHandler(mServer_ServerConnectionEstablished);
mServers[idx].ServerConnectionEnded += new CAlienServer.ServerConnectionEndedEventHandler(mServer_ServerConnectionEnded);
mServers[idx].ServerSocketError += new CAlienServer.ServerSocketErrorEventHandler(mServer_ServerSocketError);
}
private void mServer_ServerMessageReceived(string msg)
{
if (msg != null)
{
displayText(msg.Insert(msg.IndexOf(" ") + 1, "\r\n"));
}
}
private void displayText(String data)
{
try
{
if (this.InvokeRequired)
{
object[] temp = {data};
this.Invoke(new displayMessageDlgt(displayText),temp);
return;
}
else
{
txtNotifications.Text += data.Replace("\0","") + "\r\n";
Task task = insert(data);
NotifyInfo ni = null;
AlienUtils.ParseNotification(data, out ni);
if (ni != null)
{
lblReaderName.Text = ni.ReaderName;
}
}
}
catch(Exception ex)
{
Debug.WriteLine("Exception in the DiscplayText(): " + ex.Message);
}
}
我想知道运行另一个函数,将变量“data”或“msg”中的数据存储到数据库中。我知道调用同步函数将不起作用,因为如果编程正在运行将数据插入数据库函数并且阅读器拾取新标签怎么办。因此,同步功能将不起作用。我正在考虑使用异步函数。所以我的数据库插入功能是。这是正确的做法吗?
private async Task insert(string rfid)
{
await Task.Factory.StartNew(()=>
{
using (var connection = new MySqlConnection("server=localhost;user id='" + username_mysql + "';database=new;password='" + password_mysql + "'"))
{
connection.Open();
try
{
string sql = "INSERT INTO `data` (`RFID TAG`) VALUE (@rfid)";
MySqlCommand cmd = new MySqlCommand(sql, connection);
cmd.Parameters.Add("@rfid", MySqlDbType.VarChar).Value = rfid;
if (cmd.ExecuteNonQuery() == 1)
{
}
}
catch (Exception ex)
{
}
}
});
}
更新:
代码:
private void insert(string rfid)
{
using (var connection = new MySqlConnection("server=localhost;user id='" + username_mysql + "';database=alien;password='" + password_mysql + "'"))
{
connection.Open();
try
{
string sql = "INSERT INTO `data` (`DATA`) VALUE (@data)";
MySqlCommand cmd = new MySqlCommand(sql, connection);
cmd.Parameters.Add("@data", MySqlDbType.VarChar).Value = rfid;
if (cmd.ExecuteNonQuery() == 1)
{
Debug.WriteLine("Successfull: " + rfid);
textBox2.BackColor = Color.Green;
}
}
catch (Exception ex)
{
Debug.WriteLine("Exception in the insert(): " + ex.Message);
}
}
}
private void displayText(String data)
{
try
{
if (this.InvokeRequired)
{
object[] temp = {data};
this.Invoke(new displayMessageDlgt(displayText), temp);
return;
}
else
{
txtNotifications.Text += data.Replace("\0","") + "\r\n";
//await Task.Run(() => insert(data));
insert(data);
textBox2.BackColor = Color.Red;
NotifyInfo ni = null;
AlienUtils.ParseNotification(data, out ni);
if (ni != null)
{
lblReaderName.Text = ni.ReaderName;
}
}
}
catch(Exception ex)
{
Debug.WriteLine("Exception in the DisplayText(): " + ex.Message);
}
}
SERVER MESSAGE 来自 mServer_ServerMessageReceived(string msg) 方法 成功来自于 insert() 方法。
这清楚地表明所有标签数据都已插入数据库中。
调试输出:
服务器消息:00:1B:5F:00:F9:B4 0004,3,1
服务器消息:00:1B:5F:00:F9:B4 A123 0001,3,1
成功:00:1B:5F:00:F9:B4 0004,3,1
服务器消息:00:1B:5F:00:F9:B4 A641 2541,3,1
成功:00:1B:5F:00:F9:B4 A123 0001,3,1
服务器消息:00:1B:5F:00:F9:B4 0014,3,1
成功:00:1B:5F:00:F9:B4 A641 2541,3,1
服务器消息:00:1B:5F:00:F9:B4 5253 7AB2 0200 0000 0000 1002,3,1
成功:00:1B:5F:00:F9:B4 0014,3,1
服务器消息:00:1B:5F:00:F9:B4 A064 0001 0601,3,1
成功:00:1B:5F:00:F9:B4 5253 7AB2 0200 0000 0000 1002,3,1
服务器消息:00:1B:5F:00:F9:B4 0000 0000,3,1
服务器消息:00:1B:5F:00:F9:B4 0001,3,1
服务器消息:00:1B:5F:00:F9:B4 2123 6521,3,1
服务器消息:00:1B:5F:00:F9:B4 0016,3,1
成功:00:1B:5F:00:F9:B4 A064 0001 0601,3,1
成功:00:1B:5F:00:F9:B4 0000 0000,3,1
成功:00:1B:5F:00:F9:B4 0001,3,1
成功:00:1B:5F:00:F9:B4 2123 6521,3,1
成功:00:1B:5F:00:F9:B4 0016,3,1
【问题讨论】:
-
不,这不是使用异步的正确方式,原因有很多,包括use of
StartNew、fire and forget,以及“同步函数不起作用”的原因。 -
我知道调用同步函数是行不通的,因为如果程序正在运行将数据插入数据库函数并且阅读器拾取新标签怎么办。 听起来像您担心并发性。这与
async无关。 -
删除
Task.Factory.StartNew。将cmd.ExecuteNonQuery更改为await cmd.ExecuteNonQueryAsync。如果您有实际的并发问题,请发布不同的问题并提供详细信息。 -
附带说明,根据official guidelines,C# 中的方法名称遵循 PascalCase 模式。异步方法也应该有
Async后缀。所以它是InsertAsync,而不是insert。 -
@Paul 实施您的代码并进行测试,看看您是否可以重现您提到的那种问题(“运行将数据插入数据库函数并且阅读器拾取新标签”)
标签: c# mysql visual-studio asynchronous