【问题标题】:NUnit - SqlConnection timeout within TaskNUnit - 任务中的 SqlConnection 超时
【发布时间】:2021-08-15 02:42:12
【问题描述】:

我遇到了这个奇怪的问题(或者我认为我的大脑被烧毁了......)。当我从任务外部运行此代码时,它工作正常,但是当我在 Task.Run(() => ...) 内运行时,我得到一个 SqlException 超时:

public static Item GetItemById(int id)
{
    Item result;

    using (var conn = App.DbFactory.CreateConnection())
    {
         result = _repository.GetById(id, conn) ?? throw new ElementNotFoundException();
    }
    
    return result;
}

// _repository.GetById
public Item GetById(int id, IDatabaseConnection conn)
{
     Item result;
        
     var cmd = conn.CreateCommand();
     cmd.CommandText = "QUERY COMMAND";

     using (var dr = cmd.ExecuteReader()) <-- EXCEPTION
     {
          result = dr.Read() ? Create(dr) : null;
     }

     return result;
}


// Method that works.
public static Item GetItemTest()
{
    return GetItemById(12);
}

// Method that doesn't work.
public static async Item GetItemAsyncTest()
{
    return await Task.Run(() => GetItemById(12));
}

App.DbFactory.CreateConnection() 返回 IDbConnection。

更新:执行 DbCommand (ExecuteReader) 时抛出异常。

GeyById 方法仅调用存储库方法(原始 TSQL 查询)。调用者方法应该从 foreach 中读取数据库中的每个项目(使用 Task/async/await,不超过 5 个并发连接)。在这一点上,我不知道是我做错了什么还是我错过了一些概念。

我正在使用 .NET Framework 4.5 和 SQL Server 2012。

临时解决方案: 好的,我浪费了将近 6 个小时试图找出问题所在……而且是 NUnit。从测试运行 GetItemAsyncTest() 时,它会引发超时异常。从控制器运行相同的异步方法就像一个魅力。

我正在谷歌上搜索这件事。如果有人有同样的问题,我会很高兴知道它是什么:)

谢谢!!

【问题讨论】:

  • 所以你是通过多个任务并行运行这段代码?这可能意味着您正在耗尽允许的活动连接数。是否在建立连接或执行查询时发生异常?
  • 如果您多次运行相同的 SQL 代码,您可能希望重构它以执行单个批处理/连接操作
  • 我同时运行多达 5 个连接(我认为这不是问题)。执行命令时抛出异常。就像连接被阻止了一样。

标签: c# sql-server timeout task nunit


【解决方案1】:

嗯,终于解决了!这是 NUnit 和 TransactionScope 之间的一种解决方法。使用 TransactionScope(以保持数据库清洁)测试访问数据库的异步方法会在执行命令时导致超时异常。

解决此问题的方法是:升级到 NET Framework 4.5.1 并将 TransactionScopeAsyncFlowOption.Enabled 添加到 TransactionScope 构造函数中。

【讨论】:

    猜你喜欢
    • 2012-04-23
    • 2013-06-02
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2018-04-21
    相关资源
    最近更新 更多