c# - 异步执行存储过程而不等待它并阻塞 UI

标签 c# asp.net sql-server asynchronous async-await

我有几个存储过程可以插入或更新到我的 ASP.NET Web 窗体应用程序的数据库中。我希望执行这些查询,但我不希望用户的 UI 或页面执行等待它们完成。它们不会花费很长时间(不到一秒),但这是用户必须等待页面加载的一秒钟。

我通常会考虑将日志记录或历史记录插入表中。用户的页面 View 不依赖于查询的执行或结果。

我正在尝试使用 .NET 的异步方法,例如 ExecuteNonQueryAsync()。但我认为我在概念上弄错了。 ExecuteNonQueryAsync() 似乎用于并行运行两个或多个运行时间更长的数据库操作,并阻塞 UI 直到两者都完成。

private async Task<string> DoTransaction()
{
    string value = "";

    using (SqlConnection objCS = DB.AdminNET())
    {
        await objCS.OpenAsync();
        using (SqlTransaction t = objCS.BeginTransaction())
        using (SqlCommand objCommand = new SqlCommand("WAITFOR DELAY '00:00:05'; EXEC logtiming @line", objCS, t))
        {
            try
            {
                objCommand.Parameters.Add("@line", SqlDbType.VarChar).Value = "log me";
                await objCommand.ExecuteNonQueryAsync();
            }
            catch
            {
                t.Rollback();
                throw;
            }

            t.Commit();

            value = "done";
        }
    }

    return value;
}

protected async void Page_Load(object sender, EventArgs e)
{
    await DoTransaction(g);
}

此代码将在引入延迟后插入我的测试数据。但是,它会保留对用户的整个页面响应,直到延迟结束。理想情况下,我希望页面立即返回给用户,然后五秒钟后我会在表格中看到我的结果。 ExecuteNonQueryAsync() 是错误的工具吗?或者我可以做一些我还没有找到的改变,例如。 “不等待”?

最佳答案

ExecuteNonQueryAsync() seems to be... blocking the UI until both are complete.

是的,这就是 ASP.NET 的工作方式。所有其他 HTTP 服务器(如 ASP.NET Core 和 Node.js)的工作方式相同:只有一个响应要发送,并且仅在请求处理程序完成时才发送 - 无论处理程序是同步的还是异步的,都是如此。

有关更多信息,请参阅我的 article on async ASP.NET ;相关部分:

Asynchronous Code Is Not a Silver Bullet

As wonderful as asynchronous request handling is, it won’t solve all your problems. There are a few common misunderstandings around what async and await can do on ASP.NET.

When some developers learn about async and await, they believe it’s a way for the server code to “yield” to the client (for example, the browser). However, async and await on ASP.NET only “yield” to the ASP.NET runtime; the HTTP protocol remains unchanged, and you still have only one response per request. If you needed SignalR or AJAX or UpdatePanel before async/await, you’ll still need SignalR or AJAX or UpdatePanel after async/await.

解决这个问题的正确方法是使用 reliable queue with an independent background processing application .您的 Web 请求处理程序仅将一个项目放入队列中并快速返回给您的客户。然后,后台应用程序处理队列并进行实际的数据库更改。

关于c# - 异步执行存储过程而不等待它并阻塞 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56013265/

相关文章:

c# - 在 asp.net (c#) 中使用错误的文件名保存来自 SQL Server 的 Blob

c# - 在 ASP.NET 中查找使用特定接口(interface)的控件

c# - ASP.NET 核心 2.1。 MVC View 中的 Razor UI 类库

asp.net - Request.Querystring 从加密文本中删除字符

sql-server - 如何构造 SQL 语句

sql-server - 如何避免ms-sql select语句中被0除?

c# - 异步返回集合的各种方式(具有 C# 7 特性)

c# - 预测两个 double 之和

asp.net - 使用 JQUERY 将 JSON 结果添加到下拉列表

sql-server - 如何修复 SQL Server 数据库中的恢复挂起状态?