使用异步时 SqlConnection 未被释放

2024-05-03

我有一个项目,有一个 Sql-Server 数据库后端和 Dapper 作为 ORM。我正在尝试使用 Dapper 的QueryAsync()方法来获取一些数据。不仅如此,对我的存储库的调用来自几个使用 a 调用的任务内部Task.WhenAll(也就是说,每个任务都涉及从该存储库获取数据,因此每个任务都等待我的存储库的方法来包装QueryAsync()称呼)。

问题是我的 SqlConnections 永远不会关闭,即使我使用的是using堵塞。结果,我的数据库有 100 多个打开的连接,并最终开始出现“达到最大池大小”异常。问题是,当我切换到Query()代替QueryAsync(),它工作正常,但我希望能够异步执行此操作。

这是一个代码示例。我试图尽可能地模仿实际应用程序的结构,这就是为什么它看起来比实际应用程序更复杂的原因。

界面:

public interface IFooRepository<T> where T: FooBase
{
    Task<IEnumerable<T>> Select(string account, DateTime? effectiveDate = null);
}

执行:

public class FooRepository : RepositoryBase, IFooRepository<SpecialFoo>
{
    private readonly IWebApiClientRepository _accountRepository;

    public FooRepository(IWebApiClientRepository repo)
    {
        _accountRepository = repo;
    }
    public async Task<IEnumerable<FuturePosition>> Select(string code, DateTime? effectiveDate = null)
    {
        effectiveDate = effectiveDate ?? DateTime.Today.Date;
        var referenceData =  await _accountRepository.GetCrossRefferenceData(code, effectiveDate.Value);
        using (var connection = new SqlConnection("iamaconnectionstring")
        {
            connection.Open();
            try
            {
                var res = await connection.QueryAsync<FuturePosition>(SqlQueryVariable + "AND t.code = @code;",
                    new
                    {
                        effectiveDate = effectiveDate.Value,
                        code = referenceData.Code
                    });

                foreach (var item in res)
                {
                    item.PropFromReference = referenceData.PropFromReference;
                }
                return res;
            }
            catch (Exception e)
            {
                //log 
                throw;
            }
            finally
            {
                connection.Close();
            }
        }
    }
}

所以现在调用代码有两层。我将从外部开始。我想这就是问题所在。下面有评论。

人口:

public class Populator : PopulatorBase
{
    private IAccountRepository _acctRepository;
    public override async Task<IEnumerable<PopulationResult>> ProcessAccount(DateTime? popDate = null)
    {
        //My attempt at throttling the async calls
        //I was hoping this would force a max of 10 simultaneous connections.
        //It did not work.
        SemaphoreSlim ss = new SemaphoreSlim(10,10);
        var accountsToProcess = _acctRepository.GetAllAccountsToProcess();
        var accountNumbers = accountsToProcess.SelectMany(a => a.accountNumbers).ToList();

        List<Task<ProcessResult>> trackedTasks = new List<Task<ProcessResult>>();
        foreach (var item in accountNumbers)
        {
            await ss.WaitAsync();
            trackedTasks.Add(ProcessAccount(item.AccountCode, popDate ?? DateTime.Today));
            ss.Release();
        }
        //my gut tells me the issue is because of these tasks
        var results = await Task.WhenAll(trackedTasks);
        return results;
    }

    private async Task<ProcessResult>ProcessAccount(string accountCode, DateTime? popDate)
    {
        var createdItems = await _itemCreator.MakeExceptions(popDate, accountCode);
        return Populate(accountCode, createdItems);
    }
}

物品创建者:

public class ItemCreator : ItemCreatorBase
{
    private readonly IFooRepository<FuturePosition> _fooRepository;
    private readonly IBarRepository<FuturePosition> _barRepository;

    public RussellGlobeOpFutureExceptionCreator() )
    {
        //standard constructor stuff
    }
    public async Task<ItemCreationResult> MakeItems(DateTime? effectiveDate, string account)
    {
        DateTime reconDate = effectiveDate ?? DateTime.Today.Date;

        //this uses the repository I outlined above
        var foos = await _fooRepository.Select(account, effectiveDate);

        //this repository uses a rest client, I doubt it's the problem
        var bars = await _barRepository.Select(account, effectiveDate);

        //just trying to make this example less lengthy
        var foobars = MakeFoobars(foos, bars);
        var result = new ItemCreationResult { EffectiveDate = effectiveDate, Items = foobars };
        return result;
    }
}

据我尝试过:

  • 使用 SemaphoreSlim 进行节流
  • 无节流
  • Using connection.OpenAnync()在回购协议中
  • 包括/排除finally块(应该与using)

值得知道的是foreach填充器中的循环运行大约 500 次。本质上,有一个包含 500 个帐户的列表。对于每一个,都需要进行长时间的运行populate任务涉及从我的 Foo 存储库中提取数据。

老实说我不知道​​。我认为这可能与等待填充器中任务列表中每个任务的异步数据库调用有关。对这个问题的任何见解都会非常有帮助。


经过一番挖掘,我想我已经解决了这个问题。我认为我实际上并没有像我最初假设的那样遇到连接泄漏。据我现在的了解,通过连接池,当从代码中关闭 SQL 连接时,它实际上并没有消失——它只是作为空闲连接进入连接池。查看 SQL 中打开的连接仍然会显示它。

由于我的数据访问是异步的,因此在任何“关闭”连接返回到池之前打开的所有连接,这意味着为每个请求打开一个新连接。这导致我看到的打开连接数量惊人,让我认为我有连接泄漏。

使用 SemaphoreSlim 实际上解决了这个问题——我只是错误地实现了它。它应该像这样工作:

public override async Task<IEnumerable<ProcessResult>> ProcessAccount(DateTime? popDate = null)
{
      foreach (item in accountNumbers)
      {

      trackedTasks.Add(new Func<Task<ProcessResult>>(async () =>
            {
                await ss.WaitAsync().ConfigureAwait(false);
                try
                {
                    return await ProcessAccount(item.AccountCode, popDate ?? DateTime.Today).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    //log, etc.
                }
                finally
                {
                    ss.Release();
                }
            })());
      }
}

这样做会限制一次打开的连接数量,并等待它们关闭,因此池中同一较小的连接组将被重复使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用异步时 SqlConnection 未被释放 的相关文章

  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • ASP .NET MVC,创建类似路由配置的永久链接

    我需要帮助在 MVC 网站中创建类似 URL 路由的永久链接 Slug 已设置为 www xyz com profile slug 代码为 routes MapRoute name Profile url profile slug defa
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • string.Compare 行为

    怎么会这样呢 这是从VS2008中的立即窗口获取的 string Compare 1 string Compare 0 0 1 从言论来看字符串比较 http msdn microsoft com en us library 84787k2
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐

  • 如何导入名称与我的包中的模块冲突的模块?

    我的目录中有几个 python 模块 在同一目录下 我有一个包tests 我很想将模块命名为tests与它们包含测试的模块相同 尽管这当然并不重要 So in tests foo我天真地写着import foo 这不太好用 它是导入的tes
  • 如何将 Pixel 2 连接到 ADB

    我有一台已解锁并启用了 USB 调试的 Pixel 2 然而 如果我将其插入计算机 它只会显示正在充电 USB 线可以连接其他设备进行数据传输 但没有问题 所以它不是线 我可以轻松地将任何其他设备连接到我的任何端口 甚至是原来的 Pixel
  • 在 CodeIgniter 中使用 ajax 时出现 403 禁止错误

    我正在显示我的名字textbox使用 ajax 自动完成 但我的 ajax URL 不起作用 每次都显示在网络选项卡中 403 禁止 我尝试过像这样的ajax URL url baseUrl index php Employee contr
  • C++中成员函数指针是如何实现的?

    C 中的成员函数指针分为三部分 Offset Address index virtual 当使用派生对象调用时 偏移量用于指针调整base pointer 这个抵消是如何实现的 它是否指向某个表 每个派生类都有一个表 并且该表包含以下形式的
  • 访客模式说明

    因此 我已经阅读了有关访问者模式的所有文档 但我仍然非常困惑 我从另一个问题中获取了这个例子 有人可以帮助我理解吗 例如 我们什么时候使用访问者设计模式 我想我可能已经理解了一些 但我只是看不到更大的图景 我怎么知道什么时候可以使用它 cl
  • Zurb Foundation Reveal Modal - 防止后台点击关闭

    当我打开我的显示模态 http foundation zurb com docs components reveal html 我想阻止它在后台单击时关闭 这是默认行为 我正在使用 Zurb 基金会5 0 2 任何帮助 将不胜感激 如果您设
  • 表格单元格固定高度,无论单元格内容如何

    我有一个动态表 是在从用户那里获取一些输入以呈现一些表格数据后生成的 我需要知道是否可以为单元格分配固定的高度 即使其中一些单元格有一些内容 文本 我希望所有单元格的高度均为 30px 无论它们是否有内容或是否为空 这是我的CSS tabl
  • map.setMyLocationEnabled(true) 的真正作用是什么

    我正在设置 map setMyLocationEnabled true 但我想知道这到底是做什么的 我知道的 我在地图的右上角看到一个 定位我 按钮 我在地图上看到一个代表我当前位置的蓝色图标 这是我的担忧 我正在编写一个位置感知应用程序
  • Automapper 说缺少从 System.String 到 System.Char 的映射?但我没有看到 Char 属性

    我有三门课 public class UserReport Entity public string Name get set public string Email get set public List
  • 如何制作应用程序脚本以立即允许访问 Google 电子表格中的所有导入元素? [复制]

    这个问题在这里已经有答案了 I have to work with google spreadsheets I am using some template spreadsheets which all contain a lot of l
  • 蓝牙 - TX 功率和 RSSI

    我正在试验两个低功耗蓝牙 4 我在下载的 Android 应用程序上获取了 uuid tx 功率级别和 rss 值 我注意到其中一个发送 0 表示 tx 功率级别 但另一个发送 4 表示 tx 功率级别 并且在 android 应用程序上看
  • gd 的 php 包装类

    谁能推荐一个 gd 库的包装类 我找到了一个few http www bin co com php scripts classes gd image 但它们只具有基本的图像处理功能 例如翻转 倒转等 我真的在这里画画 所以我想要所有的线 点
  • <<-CONSTANT 是做什么的?

    return lt lt HTML li a href some link Link Title a li HTML 第一行的 这是一个异端邪说 http en wikipedia org wiki Here document Ruby h
  • ng-invalid-parse 类如何添加到表单中

    我正在使用自定义角度指令来验证表单中的字段 当其中一项验证失败以及自定义错误时 该类ng invalid parse也被添加到该字段中 这是正常行为吗 如果是这样 是什么原因造成的 ng invalid parse当解析器返回未定义时被添加
  • 如何获取字符串的前五个字符

    我读过这个获取第一个字符的问题 https stackoverflow com q 3878820 1716774字符串的 有没有办法从 C 中的字符串中获取前 n 个字符 您可以使用可枚举 Take http msdn microsoft
  • 将 chrome api 与 React.js 结合使用

    我一直在尝试使用 React 制作一个简单的 Chrome 扩展 清单看起来像这样 name New Tab version 1 0 manifest version 2 description A minimalist replaceme
  • Python 和 Selenium - 未知错误:元素在点 (663, 469) 处不可点击。其他元素将收到点击:

    我有这个 Selenium 代码 应该单击尺寸选择按钮 submit button driver find element by class name pro sku elementList submit button find eleme
  • 如何可视化内存中带有位域的 C 结构体的布局?

    我正在使用包括位字段的 C 结构 如下所示 struct beeper general t uint1 t enable 1 uint32 t 7 enum2 t loudness 2 uint32 t 22 enum2 t status
  • 从 BizTalk 中的平面文件中删除标头

    在 BizTalk 中从平面文件中删除标题行的最简单方法是什么 我通过为标题行 以及正文 创建一个单独的架构来实现这一点 然后将 配置管道 对话框中的 HeaderSpecName 属性设置为我刚刚创建的标题架构 然后将 PreserveH
  • 使用异步时 SqlConnection 未被释放

    我有一个项目 有一个 Sql Server 数据库后端和 Dapper 作为 ORM 我正在尝试使用 Dapper 的QueryAsync 方法来获取一些数据 不仅如此 对我的存储库的调用来自几个使用 a 调用的任务内部Task WhenA