C# wait vs Task.WaitAll在打开SqlConnection时-为什么wait会引发异常?
我有一个简单的异步方法来检查C# wait vs Task.WaitAll在打开SqlConnection时-为什么wait会引发异常?,c#,asp.net,sql-server,asynchronous,async-await,C#,Asp.net,Sql Server,Asynchronous,Async Await,我有一个简单的异步方法来检查SqlConnection是否关闭,以及是否打开: protected async Task EnsureConnectionOpenedAsync() { if (SqlConnection.State == ConnectionState.Closed && SqlTransaction == null) { await this.SqlConnecti
SqlConnection
是否关闭,以及是否打开:
protected async Task EnsureConnectionOpenedAsync()
{
if (SqlConnection.State == ConnectionState.Closed && SqlTransaction == null)
{
await this.SqlConnection.OpenAsync();
}
}
起初它工作正常,但突然它开始抛出异常“任务被取消”。当我没有更改任何涉及SqlConnection
的内容时!它只是在某种程度上停止了工作。但是在我制作了另一个版本的之后,重新连接打开了:
protected Task EnsureConnectionOpened()
{
if (SqlConnection.State == ConnectionState.Closed && SqlTransaction == null)
{
Task.WaitAll(this.SqlConnection.OpenAsync());
}
return Task.CompletedTask;
}
一切又恢复正常了
为什么会这样?我称之为的代码:
protected virtual async Task<int?> UpdateAsync(string storedProcedureName, SqlParameter[] sqlParameters)
{
try
{
SqlCommand sqlCommand = new SqlCommand(storedProcedureName, this.SqlConnection, this.SqlTransaction)
{
CommandType = CommandType.StoredProcedure,
CommandTimeout = this.CommandTimeout
};
if (sqlParameters.IsInitializedAndFilled())
{
foreach (SqlParameter sqlParameter in sqlParameters)
{
if (sqlParameter.Value == null)
{
sqlParameter.Value = DBNull.Value;
}
sqlCommand.Parameters.Add(sqlParameter);
}
}
await this.EnsureConnectionOpenedAsync();
await this.DeployStoredProcedure(storedProcedureName);
return (int)await sqlCommand.ExecuteScalarAsync();
}
catch (Exception exception)
{
this.SqlConnection.Close();
ExceptionDispatchInfo.Capture(exception).Throw();
return null;
}
}
受保护的虚拟异步任务UpdateAsync(string storedProcedureName,SqlParameter[]sqlParameters)
{
尝试
{
SqlCommand SqlCommand=新的SqlCommand(storedProcedureName、this.SqlConnection、this.SqlTransaction)
{
CommandType=CommandType.StoredProcess,
CommandTimeout=this.CommandTimeout
};
if(sqlParameters.IsInitializedAndFilled())
{
foreach(sqlParameters中的SqlParameter SqlParameter)
{
if(sqlParameter.Value==null)
{
sqlParameter.Value=DBNull.Value;
}
sqlCommand.Parameters.Add(sqlParameter);
}
}
等待此消息。确保重新连接OpenedAsync();
等待此消息。部署StoredProcedure(storedProcedureName);
return(int)wait sqlCommand.ExecuteScalarAsync();
}
捕获(异常)
{
this.SqlConnection.Close();
ExceptionDispatchInfo.Capture(exception.Throw();
返回null;
}
}
问题非常简单-调用UpdateAsync
命令的方法没有等待它(并且没有分别标记为async
)。因此,仔细查看您的async
代码-您应该在任何地方等待它。除非您正在共享连接对象,否则名为EnsureConnectionOpened
(async
)的方法几乎没有什么用处。这几乎总是以糟糕的结局收场。让这些对象保持本地并共享连接字符串几乎总是更好的。@Damien_不信者明白了你的意思,这个方法实际上是本地的,从来没有在其他CLLSE中使用过,我可能应该这样做private@el_nektarin这并不是说要保密。事实上,您的连接应该是一个局部变量,而不是一个字段或属性。