ExecuteScalarAsync挂起,但ExecuteScalar立即返回

本文关键字:返回 ExecuteScalar 挂起 ExecuteScalarAsync | 更新日期: 2023-09-27 17:59:16

所以我遇到了一个困扰我的小问题,我一直找不到一个好的解释——我想我可能在某种程度上错误地使用了异步/等待功能,但我真的不知道我做错了什么。

所以我有一些sql代码来查询我的数据库并返回一个值。因此,我使用ExecuteScalarAsync将该值输出到c#中。

代码如下:

public void CheckOldTransactionsSync()
{
    CheckOldTransactions().Wait();
}
public async Task CheckOldTransactions()
{
    DateTimeOffset beforeThis = DateTime.UtcNow.Subtract(TimeSpan.FromHours(6));
    using (SqlConnection connection = new SqlConnection(SqlConnectionString))
    {
        await connection.OpenAsync(cts.Token);
        using (SqlCommand command = new SqlCommand(@"SELECT TOP 1 1 AS value FROM SyncLog WHERE [TimeStamp] < @BeforeThis;", connection))
        {
            command.Parameters.Add("@BeforeThis", System.Data.SqlDbType.DateTimeOffset, 7);
            command.Prepare();
            command.Parameters["@BeforeThis"].Value = beforeThis;
            Int32 oldTransactions = (Int32)await command.ExecuteScalarAsync(cts.Token);
            // do stuff with oldTransactions
        }
    }
}

因此,在我的代码的其他地方,创建了名为cts的CancellationTokenSource,并使用CancelAfter方法将其设置为2分钟后过期。

现在,我已经使用调试器逐步完成了这段代码,并顺利到达等待调用ExecuteScalarAsync的行。然而,我在执行该行时似乎有两个问题,一是它似乎没有返回,二是它忽略了我的取消令牌,并且在我的两分钟取消令牌到期后仍在运行。

现在我已经在SqlStudio中运行了sql查询,它的返回速度非常快——此时表只有大约4000行。

我现在已经通过将该行更改为:来解决问题

Int32 oldTransactions = (Int32) command.ExecuteScalar();

它几乎在瞬间返回。

这是我修改过的唯一一行代码,我把它改回来只是为了确保同样的问题发生。所以我的问题是,我对异步调用做错了什么?

ExecuteScalarAsync挂起,但ExecuteScalar立即返回

您正在调用Wait

这是典型的ASP.NET死锁。不要阻塞或使用同步IO。