[英]How do I avoid “Access Violation” during asynchronous database connections?
我知道我的應用程序本身至少非常接近正確,因為它執行一次正確,所以我知道我可以消除防火牆、錯誤的數據庫密碼、過程名稱等的常見嫌疑。
private async Task<T> executeAsyncHelper<T>(Func<IDataReader, T> then)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(name, conn))
{
parameters.Select(p => cmd.Parameters.Add(p))
.ToImmutableList();
cmd.CommandType = CommandType.StoredProcedure;
using (IDataReader rdr = await cmd.ExecuteReaderAsync())
{
return then(rdr);
}
}
}
}
該方法在同一過程中被調用兩次。 第一次,它成功更新了數據庫。 第二次,整個事情在conn.Open()
上以“訪問沖突”轉儲。 重要的是,它不會引發異常。 相反,整個調試器以負狀態碼退出。
這是調試器 output 的最后兩行(調試器 output 的 rest 看起來正常):
The program '[6904] dotnet.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
The program '[6904] dotnet.exe: Program Trace' has exited with code 0 (0x0).
這種行為是 100% 可重復的。
據我所知,最可能的原因是異步打開兩個連接存在一些問題,但我不立即知道如何處理該假設。 我已經盡可能安全地編寫了該方法。
其次,我檢查了我的 Azure SQL 服務器實例是否有任何異常限制。 這是一個基本實例,但我懷疑這是問題所在,因為如果這是問題所在,我預計會出現 SQL 異常(調試器將中斷並顯示正常的堆棧跟蹤)。
是否有人看到我實施此方法的方式有任何問題,或者有任何建議以了解有關該錯誤的更多信息?
嘗試這個:
private async Task<T> executeAsyncHelper<T>(Func<IDataReader, Task<T>> then)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(name, conn))
{
parameters.Select(p => cmd.Parameters.Add(p))
.ToImmutableList();
cmd.CommandType = CommandType.StoredProcedure;
using (IDataReader rdr = await cmd.ExecuteReaderAsync())
{
return await then(rdr);
}
}
}
}
注意簽名的更改,並等待return
。
為了檢查您沒有達到連接限制,您可以執行 exec sp_who2 並查看 sql 服務器上有多少連接。 如果 sql 服務器上顯示的連接很多,則可能是由於資源問題。 您是否嘗試過以常規方式同步運行此代碼並導致同樣的問題? 您的連接字符串上是否有任何限制連接數的內容? 因為我沒有看到這段代碼的上下文,所以只是拋出了一些理論。
很自信我想通了。 它實際上與程序死亡的確切行沒有任何關系。
相反,程序在不同線程的其他地方溢出了堆棧。 conn.Open()
是一個紅鯡魚,即使那是調試器在它失敗之前總是指向的地方。 我的猜測是conn.Open()
只是資源密集型足以將其置於邊緣以使其看起來像是造成它的原因。
以供將來參考,如果您遇到“訪問沖突”,則重構為同步代碼,然后調試器將能夠直接執行並實際拋出 StackOverflowException 而不是崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.