【问题标题】:SqlConnection.OpenAsync() hangs when there are no active connections没有活动连接时,SqlConnection.OpenAsync() 挂起
【发布时间】:2014-10-17 18:36:59
【问题描述】:

当我运行这个时:

using(SqlConnection connection = new SqlConnection(connectionString)){
    await connection.OpenAsync();
}

它挂在connection.OpenAsync() 线上。

如果我在 Sql Server Management Studio 中查看数据库有多少活动连接,那么只有一个:可能是这段代码使用的那个。所以,我不确定是不是我的应用程序池中的连接用完了。

我做错了什么?

【问题讨论】:

  • 我猜你的连接字符串是错误的。
  • 你等了多久?
  • 1) 如果你做一个正常的打开它是否有效? 2) 如果你把它放在using 语句之前,它会锁定在await Task.Delay(1000); 上吗?如果两个问题都是肯定的,那么您的问题与 SQL 无关,您的真正问题在 stackoverflow.com/questions/14485115/… 中进行了解释
  • @ScottChamberlain 啊,就是这样。 async/await 功能非常好,但很容易让自己陷入困境。
  • 它也不承认取消令牌。我设置了取消令牌,但如果无法建立连接,它仍会设置在那里并超时,而不是在设置取消令牌时立即返回。完全没用。此外,我调用 OpenAsync 的唯一原因是利用取消令牌——只是发现它根本不起作用——因为没有异步版本的 Database.BeginTransaction。真是一堆半途而废的工作。

标签: sql-server ado.net


【解决方案1】:

问题根本不在于连接。问题是我在我的线程上陷入僵局时开枪打中了自己的脚。我试图对包含connection.OpenAsync() 的方法进行同步调用,如下所示:

Task task = MyAsyncMethod();
task.Wait();

通过调用task.Wait() 我阻塞了线程。当await connection.OpenAsync() 返回时,该方法的其余部分希望在我刚刚阻塞的同一个线程上运行,因此任务永远不会完成,task.Wait() 永远不会返回。

解决方案:
因为在我的异步方法中,我不需要坚持调用它的同一个线程,我只是使用了await connection.OpenAsync().ConfigureAwait(false),让它在另一个线程中运行该方法的其余部分,而不是我用task.Wait() 阻止的线程.

【讨论】:

【解决方案2】:

它可能挂起的另一个原因是因为实施很糟糕。 OpenAsync(CancellationToken) 甚至不使用取消令牌进行 Open 操作,因此您实际上无法取消它。您必须等待它超时。如果在调用该方法时已经设置了cancellationToken,它所做的只是返回一个已取消的任务,您可以在没有任何特殊实现的情况下检查自己。所以这个“异步”重载实际上是没有用的。

【讨论】:

  • 那个实现看起来根本不像是异步的。 open() 操作是同步完成的,在任务返回时,其结果已经设置好了。
  • @AxiomaticNexus Open 调用 private bool TryOpen(TaskCompletionSource<DbConnectionInternal> retry) - reference source
  • 图中的OpenAsync 是来自DbConnection 类的虚方法。只有当数据提供者类不包含OpenAsync 的覆盖时,才会调用该方法。而这个问题中引用的SqlConnection 类具有这样的覆盖。见来源:now.NET Framework 4
  • 嗯。不,我是对的。即使在您引用的源中,传递给 OpenAsync 的 cancelToken 也不会传递给 TryOpen。将任务完成源(不参考接收到的 cancelToken)传递给 TryOpen。看起来 TryOpen 可能会立即返回并打开连接。但是,如果它没有完成,取消只是等待操作完成(或取消未来的重试尝试),而不是“打开”操作本身。同样,cancellationToken 根本没有传递给 TryOpen,因此它不可能取消实际的连接尝试。
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 2022-01-15
  • 2016-11-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多