首页 > 解决方案 > 异步调用阻塞mysql连接

问题描述

我有一个网格,其中每一行都有一个按钮,单击按钮启动异步进程并在 mysql 的数据库中插入一些记录

当我在未完成第一次调用的情况下单击网格上的另一个按钮时,即使我再次启动它,整个事情也停止工作并且页面抛出错误

错误信息

MySql.Data.MySqlClient.MySqlException:'超时已过期。在操作完成之前超时时间已过或服务器没有响应。

它卡在无限循环中,我的应用程序的整个服务器都被阻止了,即使我的本地服务器也无法正常工作

按钮点击按钮

protected void btnRun_Click(object sender, EventArgs e)
{
    RadButton btn = sender as RadButton;
        
    Task.Factory.StartNew(async () =>
    {
        await RunAsync(btn, num, int.Parse(Session["UserID"].ToString()));
        btn.Enabled = true;
        btn.ToolTip = "Job Complete";
    });
}    

public async Task RunAsync(RadButton btnRn, int batch, int userId)
{

    RadButton btn = btnRn as RadButton;
    string hwid = btn.CommandArgument;
    if (hwid != null && hwid != string.Empty)
    {
        //all 
        IEnumerable<CaseDetails> lstFilterHwList = lstCaseFiltered.Where(f => f.HWID == int.Parse(hwid)).ToList();
        lstJobs = lstJobs.Where(f => f.HWID == int.Parse(hwid) && f.StatusName.ToUpper() != "DONE").ToList();
        lstFilterHwList = lstFilterHwList.Where(f => !lstJobs.Any(lk => lk.JobContent == f.CaseID)).ToList();
        
        if (lstFilterHwList.Count() > 0)
        {

            foreach (CaseDetails caseDetail in lstFilterHwList)
            {

               
             
                if (printer != null)
                {
                    
                    //Station station = deviceRepository.GetStation(stationLocation);
                    if (station != null)
                    {
                        using (var httpClient = new HttpClient())
                        {
                            JobContent content = new JobContent();
                            content.JobName = "TDMSID_" + tdmsCase.TestCaseId;
                            content.JobFrom = "TED";
                            // Logger.WriteMessageToLog_AutoExcute("HwID" + printer.HWID);
                            content.HwId = printer.HWID;
                            content.Firmware = caseDetail.Firmware;
                            content.PrinterIP = printer.ADDRESS;
                           
                            content.MachineIP = station.StationIP;
                            content.MachineTypeID = "1";
                            content.userId =  tdmsUser.ZCATUID; //userId;//tdmsUser.ZCATUID;
                            content.ProjectId = 0;
                            content.ToolName = "ZCAT Plus";
                            content.AutomationId = caseDetail.CaseID.ToString();
                            content.DatabaseServer = "Test";
                            content.BatchID = batch;
                            string apiUrl = string.Empty;
                            
                            apiUrl = "http://xx.xx.xx.xx:8090/api/Jobs";
                            var response = await httpClient.PostAsync(apiUrl, CreateHttpContent<JobContent>(content));
                            //response.StatusCode
                            // response.EnsureSuccessStatusCode();
                            var data = await response.Content.ReadAsStringAsync();
                          

                        }

                    }
                   

                    
                }
               
            }
        }        
    }
}

标签: c#mysqlasp.netasynchronousasync-await

解决方案


主要问题和问题是:

await RunAsync(btn, num, int.Parse(Session["UserID"].ToString()));

所以你阻止代码并告诉它等到完成?为什么要费心做所有的工作来设置异步调用,然后通过告诉它无论如何都要等待而抛弃这个想法的好处?调用 somthing async 很棒,但是 callit 和 await 并告诉它等待在这里达到零,实际上你告诉它等待你根本没有异步。

请记住,单击按钮时,整个网页都会进入服务器。然后你的代码开始运行。直到该代码退出子程序,然后一切都被阻止,直到该代码完成并“返回”。代码完成后(退出子),然后将网页发送回浏览器。

因此,您不能将代码捆绑在后面,因为这会占用服务器上的网页。按钮代码必须快速出现。因此,您单击,调用例程异步(无等待),然后网页现在可以返回浏览器。

那么,在您为设置该异步调用所做的所有努力之后?然后,您使用“等待”将整个事情分开。这意味着您的代码现在又回到了等待代码完成的状态。实际上,您不再异步了。该网页将卡在该例程中(并卡在服务器端)。

您必须删除 await 命令,并且必须让该代码运行。

所以,你必须删除等待。您不能阻止或等待代码,因为如果这样做,则网页位于服务器端,并且没有按钮单击或任何客户端都可以工作。

它是这样工作的:

Your button click.
    --> web page travels up to server)
    --> code behind starts running
    --> code behind WHEN DONE - exit subs
    --> web page travels back down to client side
    --> user (client side)  now gets a whole new fresh page with controls updated.

 Your code behind cannot WAIT or the web page is blocked
 Code behind can call routines async and that is ok, but without waits

所以,你背后的代码不能等待。您必须删除 await 命令,并且该代码必须运行并返回。


推荐阅读