我知道我的应用程序本身至少是 差不离 纠正,因为它执行正确 曾经所以我知道我可以排除防火墙、错误的数据库密码、过程名等常见的嫌疑。
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()
与 "访问违规"。重要的是,它没有抛出异常。而是整个调试器以负状态码退出。
这是调试器输出的最后两行(其余的调试器输出看起来很正常)。
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 Server实例是否对它有任何异常限制。这是一个基本的实例,但我怀疑这是问题所在,因为如果是这个问题的话,我预计会出现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,而不是直接崩溃。