【问题标题】:Await vs Task.WaitAll while openning SqlConnection - why does Await throw an exception?打开 SqlConnection 时等待与 Task.WaitAll - 为什么等待抛出异常?
【发布时间】:2020-04-20 00:52:03
【问题描述】:

我有一个简单的异步方法来检查 SqlConnection 是否已关闭,如果是 - 打开它:

protected async Task EnsureConnectionOpenedAsync()
        {
            if (SqlConnection.State == ConnectionState.Closed && SqlTransaction == null)
            {
                await this.SqlConnection.OpenAsync();
            }
        }

一开始它工作正常,但突然开始抛出异常"A task was cancelled"。当我没有改变任何触及SqlConnection的东西时!它只是以某种方式停止了正常工作。但是在我制作了另一个版本的EnsureConnectionOpened之后:

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

【问题讨论】:

  • 除非您共享连接对象,否则称为EnsureConnectionOpened (Async) 的方法很少使用。这几乎总是以糟糕的方式结束。几乎总是更好地将这些对象保持在本地并仅共享连接 string.
  • @Damien_The_Unbeliever 明白了你的意思,这种方法实际上是本地的,从未在其他类中使用过,我可能应该将其设为私有
  • @el_nektarin 这不是为了将其设为私有。事实上,你的连接应该是一个局部变量,而不是一个字段或属性。

标签: c# asp.net sql-server asynchronous async-await


【解决方案1】:

问题很简单——调用UpdateAsync 命令的方法没有等待它(并且没有分别标记为async)。因此,请仔细查看您的 async 代码 - 您应该在任何需要的地方等待它。

【讨论】:

    猜你喜欢
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 2018-08-26
    • 2016-09-12
    相关资源
    最近更新 更多