所以我遇到了一個令我困惑的小問題,我一直無法找到一個很好的解釋 - 我想我可能會錯誤地使用異步/等待功能不知何故,但我真的不知道我做錯了什麼。ExecuteScalarAsync掛起,但ExecuteScalar立即返回
所以我有一些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
}
}
}
所以在我的代碼的其他地方的CancellationTokenSource稱爲CTS創建和設置使用CancelAfter方法2分鐘後到期。
現在我已經通過調試器遍歷了這段代碼,並且到達了等待ExecuteScalarAsync調用沒有問題的那一行。不過,我似乎有兩個問題與執行該行,它似乎並沒有返回,2它忽略了我的取消令牌,並且在我的兩分鐘取消令牌過期後仍然運行一段時間。
現在我已經在Sql Studio中運行了sql查詢,並且它非常快速地返回 - 表格目前只有大約4000行。
Int32 oldTransactions = (Int32) command.ExecuteScalar();
幾乎在瞬間返回:
我通過改變線路解決了這個問題現在。
這是我更改的唯一代碼行,我將其更改回來以確保發生相同的問題。所以我的問題是,我對異步調用做了什麼錯誤?
你打電話給'Task.Wait'還是'Task .Result'進一步調用你的調用棧?如果是這樣,你可能會看到我在博客上解釋的[死鎖](http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)。 –
請問您可以添加顯示您如何調用CheckOldTransactions()的代碼,以及如何等待它的完成? – Nitram
嗨,斯蒂芬,是的,我確實在這種情況下用.Wait()來調用它 - 我會閱讀你的博客,看看它是否有幫助。謝謝 – m3z