簡體   English   中英

如何在異步數據庫連接期間避免“訪問沖突”?

[英]How do I avoid “Access Violation” during asynchronous database connections?

目標:正確使用 ExecuteAsync。

我知道我的應用程序本身至少非常接近正確,因為它執行一次正確,所以我知道我可以消除防火牆、錯誤的數據庫密碼、過程名稱等的常見嫌疑。

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);
            }
        }
    }
}

問題:第二個SqlConnection.Open() 上的訪問沖突

該方法在同一過程中被調用兩次。 第一次,它成功更新了數據庫。 第二次,整個事情在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 異常(調試器將中斷並顯示正常的堆棧跟蹤)。

環境信息

  • Azure SQL 服務器 2016
  • Windows 10
  • .NET 核心2.1
  • 視覺工作室 2017

結論

是否有人看到我實施此方法的方式有任何問題,或者有任何建議以了解有關該錯誤的更多信息?

嘗試這個:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM