我被赋予了重写一些用 C# 编写的库的任务,这样一旦启动完成就没有分配。
我刚做了一个项目,该项目每 30 秒通过 OdbcConnection 进行一些数据库查询。我一直只使用创建 OdbcDataReader 的 .ExecuteReader()。是否有任何模式(如 SocketAsyncEventArgs 套接字模式)可以让您重新使用自己的 OdbcDataReader?或者其他一些避免分配的聪明方法?
我没有费心去学习 LINQ,因为工作中的所有数据库都是基于 Oracle 的,而我最后一次检查时,没有官方的 Linq To Oracle 提供程序。但如果在 Linq 中有一种方法可以做到这一点,我可以使用第三方方法之一。
更新:
我认为我没有明确说明 no-alloc 要求的原因。我们有一个关键线程正在运行,它不会冻结非常重要。这是一个近乎实时的交易应用程序,我们确实看到某些 Gen 2 集合的冻结时间长达 100 毫秒。(我也听说过用 C# 以同样的方式编写游戏)。有一个后台线程会进行一些合规性检查,每 30 秒运行一次。它现在进行数据库查询。查询非常慢(返回所有数据大约需要 500 毫秒),但这没关系,因为它不会干扰关键线程。除非工作线程正在分配内存,否则会导致 GC 冻结所有线程。
有人告诉我,所有库(包括这个库)在启动后都无法分配内存。无论我是否同意,这都是签署支票的人的要求:)。
现在,显然有一些方法可以让我在没有分配的情况下将数据放入这个过程。我可以设置另一个进程并使用套接字将其连接到这个进程。使用新的 SocketAsyncEventArgs 模式,新的 .NET 3.5 套接字经过专门优化,根本不分配。(事实上,我们使用它们来连接多个系统,并且从未看到来自它们的任何 GC。)然后有一个从套接字读取并遍历数据的预分配字节数组,沿途不分配任何字符串。(我不熟悉 .NET 中其他形式的 IPC,所以我不确定内存映射文件和命名管道是否分配)。
但是,如果有一种更快的方法来完成这个 no-alloc 查询而无需经历所有的麻烦,我会更喜欢它。