Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中正确使用异步?_C#_Mysql_Visual Studio_Asynchronous - Fatal编程技术网

如何在C#中正确使用异步?

如何在C#中正确使用异步?,c#,mysql,visual-studio,asynchronous,C#,Mysql,Visual Studio,Asynchronous,我有一个来自供应商的演示应用程序。这个演示应用程序允许我通过网络连接到RFID阅读器。一旦建立了连接,我就可以扫描RFID标签,然后标签数据就会显示在应用程序上 每当CAlienServer接收到来自RFID阅读器的消息时,就会引发eventhandler private void addServerEvents(int idx) { mServers[idx].ServerMessageReceived += new CAlienServer.ServerMessageReceived

我有一个来自供应商的演示应用程序。这个演示应用程序允许我通过网络连接到RFID阅读器。一旦建立了连接,我就可以扫描RFID标签,然后标签数据就会显示在应用程序上

每当CAlienServer接收到来自RFID阅读器的消息时,就会引发eventhandler

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)
        {
            
        }
    }
   });
}
错误1:

更新:

代码:

服务器消息来自mServer_ServerMessageReceived(字符串消息)方法 successfull来自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,3,1

成功:00:1B:5F:00:F9:B4 0001,3,1

成功:00:1B:5F:00:F9:B4 21236521,3,1

成功:00:1B:5F:00:F9:B4 0016,3,1

您可能应该改用。请注意,这可能会也可能不会实际执行异步

对于Oracles MySql连接器,所有异步方法。声称提供真正的异步支持,但我还没有对此进行测试。(感谢布拉德利·格兰杰提供更多信息。)

如果您确定查询实际上是同步运行的,那么在后台线程上运行查询可能是合理的,以避免阻塞UI(如果是UI应用程序)。如果是这样的话,那么最好先创建一个同步方法

private void insert(string rfid){
    ...
}
然后像这样称呼它

private async Task displayText(String data){
    ....
    await Task.Run(() => insert(rfid));
    ...
}
如果这样做,则需要确保该方法是线程安全的。如果不能保证这一点,则不应在其他线程上运行它。请注意,您应该确保正确处理异常。即

  • 避免空捕获,所有异常都应该以某种方式处理。如果无法插入所需的数据,则可能会通知用户
  • 应等待所有任务,否则将丢失任何异常
  • 避免使用
    async void
    ,因为这使得调用者无法等待,因此无法接收任何异常
  • 对于事件处理程序(即按下按钮),您需要使用
    async void
    ,在这种情况下,您应该确保捕获任何异常并采取适当的操作。可能会通知用户故障,和/或终止应用程序

不,这不是使用async的正确方法,原因有很多,包括“同步函数将不起作用”的原因。我知道调用同步函数将不起作用,因为如果编程正在运行将数据插入数据库函数的操作,并且读卡器拾取新的标记,该怎么办。听起来你很关心并发性。这与
async
无关。删除
Task.Factory.StartNew
。将
cmd.ExecuteNonQuery
更改为
wait cmd.executenonquerysync
。如果你有一个实际的并发问题,发布一个不同的问题并包括详细信息。根据C#中的方法名称,请遵循PascalCase模式。异步方法也应该有后缀。因此,它是
InsertAsync
,而不是
insert
@Paul实现您的代码并进行测试,看看您是否可以重现您提到的那种问题(“将数据插入数据库函数,然后读取器拾取新标记”),将displayText()设置为异步方法与insert()之间有什么区别请注意,对于MySql.Data,所有“异步”方法实际上都是同步执行的:在.NET中使用MySql实现真正异步I/O的唯一方法是切换到不同的ADO.NET库:@Paul,无论何时调用异步方法,都需要处理结果,即使这只是一个执行选项,也可以通过等待来轻松完成。因此,调用方还需要是
异步任务
。这将一直持续到您可以适当处理异常的程度,可能是在UI层。@Bradley Grainger感谢您提供的信息,并将其添加到了答案中。我也这么怀疑,但没有参考资料。@Paul有很多指南和最佳实践描述了如何处理异常。也许是个好的开始。
private async Task displayText(String data){
    ....
    await Task.Run(() => insert(rfid));
    ...
}