C# 我如何避免;访问违规”;在异步数据库连接期间? 目标:正确使用ExecuteAsync。
我知道我的应用程序本身至少非常接近正确,因为它只正确执行一次,所以我知道我可以消除防火墙、错误的数据库密码、过程名称等常见问题C# 我如何避免;访问违规”;在异步数据库连接期间? 目标:正确使用ExecuteAsync。,c#,.net-core,ado.net,task-parallel-library,sqlconnection,C#,.net Core,Ado.net,Task Parallel Library,Sqlconnection,我知道我的应用程序本身至少非常接近正确,因为它只正确执行一次,所以我知道我可以消除防火墙、错误的数据库密码、过程名称等常见问题 private async Task<T> executeAsyncHelper<T>(Func<IDataReader, T> then) { using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open();
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);
}
}
}
}
这种行为是100%可重复的
假设:连接池和异步性
据我所见,最可能的原因是异步打开两个连接时出现了一些问题,但我不知道如何处理这个假设。我已经尽我所知安全地编写了这个方法
其次,我检查了我的Azure SQL Server实例是否有任何异常限制。这是一个基本实例,但我怀疑这是否是问题所在,因为如果这是问题所在,我会期望出现SQL异常(调试器将中断并显示正常的堆栈跟踪)
环境信息
- Azure SQL Server 2016
- 视窗10
- .NET核心2.1
- Visual Studio 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);
}
}
}
}
专用异步任务执行同步器(Func-then)
{
使用(SqlConnection conn=newsqlconnection(connectionString))
{
conn.Open();
使用(SqlCommand cmd=newsqlcommand(名称,conn))
{
parameters.Select(p=>cmd.parameters.Add(p))
.ToImmutableList();
cmd.CommandType=CommandType.storedProcess;
使用(IDataReader rdr=await cmd.ExecuteReaderAsync())
{
返回等待时间(rdr);
}
}
}
}
请注意签名的更改,并等待返回尝试以下操作:
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);
}
}
}
}
专用异步任务执行同步器(Func-then)
{
使用(SqlConnection conn=newsqlconnection(connectionString))
{
conn.Open();
使用(SqlCommand cmd=newsqlcommand(名称,conn))
{
parameters.Select(p=>cmd.parameters.Add(p))
.ToImmutableList();
cmd.CommandType=CommandType.storedProcess;
使用(IDataReader rdr=await cmd.ExecuteReaderAsync())
{
返回等待时间(rdr);
}
}
}
}
请注意对签名的更改,并等待返回,以便检查是否达到连接限制,您可以执行exec sp_who2并查看sql server上有多少连接。如果sql server上显示了大量连接,这可能是由于资源问题造成的。您是否尝试过在常规同步模式下运行此代码,并且是否导致了相同的问题?您的连接字符串中是否有限制连接数的内容?因为我看不到这段代码的上下文,所以我需要抛弃一些理论 为了检查是否达到连接限制,您可以执行exec sp_who2并查看sql server上有多少连接。如果sql server上显示了大量连接,这可能是由于资源问题造成的。您是否尝试过在常规同步模式下运行此代码,并且是否导致了相同的问题?您的连接字符串中是否有限制连接数的内容?因为我看不到这段代码的上下文,所以我需要抛弃一些理论 我很有信心地找到了答案。事实上,这与程序即将消亡的确切路线没有任何关系
相反,程序在另一个线程的其他位置溢出堆栈。conn.Open()
是一个麻烦事,尽管调试器总是在失败之前指出这一点。我的猜测是,conn.Open()
是资源密集型的,足以将其置于边缘,使其看起来像是导致它的原因
作为将来的参考,如果您得到“访问冲突”,则重构到同步代码,然后调试器将能够直接遍历并实际抛出StackOverflowException,而不仅仅是崩溃 我很有信心地找到了答案。事实上,这与程序即将消亡的确切路线没有任何关系
相反,程序在另一个线程的其他位置溢出堆栈。conn.Open()
是一个麻烦事,尽管调试器总是在失败之前指出这一点。我的猜测是,conn.Open()
是资源密集型的,足以将其置于边缘,使其看起来像是导致它的原因
作为将来的参考,如果您得到“访问冲突”,则重构到同步代码,然后调试器将能够直接遍历并实际抛出StackOverflowException,而不仅仅是崩溃 参数的位置和内容是什么?你能把它也包括在内吗?没有说这是原因,但这是我唯一看不到的:)另外,您的函数是async Task
,但您没有等待Func
,因此我建议您将传入的函数的签名更改为也是异步的,例如Func
,调试器会说什么?好的,用注释编号:1<代码>参数
与连接字符串和过程名称一起注入构造函数。失败时的内容与成功时的内容非常接近,所以我认为这不是原因。尽管如此,问一问也无妨。2.只是进行了重构,但似乎没有什么帮助。3.调试器并不是真的在说什么。当我跨过conn.Open()
时,调试器只会带着上面的日志退出。工作假设:我想知道我的代码是否是令人尴尬的并行。我将尝试同步性,看看这是否对我有帮助。谢谢你的努力!然而,对于一个形式奇妙的问题,你会得到+1。在哪里,什么是参数<