在 C# .NET 中清理 ODBC DSN

Posted

技术标签:

【中文标题】在 C# .NET 中清理 ODBC DSN【英文标题】:Cleaning up ODBC DSN in C# .NET 【发布时间】:2009-08-25 16:23:20 【问题描述】:

我正在使用 C# 和 OBDC DSN 连接到 Paradox 数据库。如果我打开和关闭每个连接,我似乎正在泄漏内存。

我的代码基本上是:

            csb.Dsn = "DNSName";
            OdbcConnection con = new OdbcConnection(csb.ConnectionString);
            con.Open();

            OdbcCommand comm= new OdbcCommand("SELECT * FROM Tabl", con);
            OdbcDataReader reader= null;
            try
            
                reader= comm.ExecuteReader();
                for (int count = 0; (count < 5 && reader.Read()); ++count)
                
                    //Read
                
            
            finally
            
                if (reader!= null)
                
                    reader.Close();
                    reader.Dispose();
                
                if (comm!= null)
                
                    con.Close();
                    con.Dispose();
                    OdbcConnection.ReleaseObjectPool();
                    GC.Collect();
                    comm.Dispose();
                
            

有什么想法或建议吗?

更新 1

我将其更改为使用 statments,仍然泄漏。

【问题讨论】:

如果 comm 为空,您将不会关闭连接。我看不出这里怎么会发生这种情况,但您可能想检查 con 是否为空并关闭/处置它,而不是检查 comm。另外,建议你看看 using 关键字。 您使用什么来确定您的应用程序正在泄漏内存? 内存使用率不断攀升,而且很快,然后当我停止所有线程时,它永远不会回到基线,或者根本没有下降。 您使用哪种 Paradox ODBC 驱动程序? GC.Collect 不应该是必要的。 哇,这是一个旧线程,但我遇到了同样的问题 - 使用块并不能解决问题。有人有什么新鲜想法,或者 OP 找到解决方案了吗? 【参考方案1】: 使用 (var connection = new OdbcConnection(csb.ConnectionString)) 连接.打开(); 使用 (var command = new OdbcCommand("SELECT * FROM Tabl", connection)) 使用 (var reader = command.ExecuteReader()) for (var count = 0; (count

上述代码中没有内存泄漏,除非它是在“// Read”执行点创建的。 GC.Collect 永远不应该在生产中使用;它很可能无论如何都无济于事,并且实际上可能会阻碍 GC,因为它是自我调整的。使用像 ANTS Memory Profiler 这样的分析器(或免费试用),看看你的对象上挂着什么。

Do not trust the Windows Task Manager to show you whether you have leak。确保为此目的使用分析器。

【讨论】:

【参考方案2】:

尝试将连接、命令和读取器放入 using 语句中。

然后拨打OdbcConnection.ReleaseObjectPool(); 最后。

注意:垃圾收集运行可能需要几分钟时间。为了证明没有泄漏,您可以连续调用 3 次 GC.Collect() [清除所有 3 代中的对象 3 次]。

不要将GC.Collect() 留在生产代码中,因为它可能会对性能造成很大影响。

【讨论】:

【参考方案3】:

您是如何检测到泄漏的?有时,任务管理器中的内存使用量上升并且没有立即释放可能是由于 GC 没有立即启动,或者您的连接池或句柄尚未在托管环境中释放。我建议您使用 Travis 建议的 ANTS Mem Profiler 之类的内存分析器。您可以获得试用版,否则使用 Microsoft CLRProfiler 的基本版。

另一个很好的措施是加载进程以使其在分析过程中运行更长时间,以便在出现问题时清楚地显示出来。最简单的方法是在它周围放置一个循环,以便将上面的代码运行 1000 次或更多。您还可以使用性能监视器来监视一些感兴趣的计数器,并查看它们在执行期间如何跟踪。

【讨论】:

【参考方案4】:

尽量避免调用 GC.Collect

除非您 100% 确定自己知道自己在做什么,否则切勿触摸垃圾收集器。永远记住——垃圾收集器比你聪明,它知道运行的最佳时间。

【讨论】:

以上是关于在 C# .NET 中清理 ODBC DSN的主要内容,如果未能解决你的问题,请参考以下文章

使用 VB.NET 创建 ODBC DSN

C# -- 使用ODBC连接数据库

如何使用 ASP.Net 数据源通过 ODBC DSN 连接到 Access 数据库?

ODBC 机器 DSN 设置存储在 Windows 中的啥位置?

在 C# 应用程序退出时清理非托管 C++ 线程

在构建/保存和提交时设置 C# editorconfig 代码清理