ExecuteScalarAsync挂起但ExecuteScalar立即返回

时间:2015-06-24 10:13:51

标签: c# sql-server async-await

所以我遇到了一个让我感到困惑的小问题,而且我还没有找到一个好的解释 - 我想我可能错误地使用了async / await功能不知怎的,但我真的不知道自己做错了什么。

所以我有一些查询我的数据库的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而没有问题的行。但是我似乎有两个执行该行的问题,它似乎没有返回,2它忽略了我的取消令牌,并且在我的两分钟取消令牌到期后仍然运行一段时间。

现在我在Sql Studio中运行sql查询并且返回非常快 - 此时表只有大约4000行。

我现在通过将该行更改为:

来解决问题
Int32 oldTransactions = (Int32) command.ExecuteScalar();

几乎瞬间回归。

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

1 个答案:

答案 0 :(得分:4)

您正在呼叫Wait

这是classic ASP.NET deadlock.不要阻止,或使用同步IO。