我有几个存储过程可以插入或更新到我的 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/