C# IDisposable 正确用法和调用

Posted

技术标签:

【中文标题】C# IDisposable 正确用法和调用【英文标题】:C# IDisposable correct usage and call 【发布时间】:2012-04-19 18:24:05 【问题描述】:

这可能是一个新手问题,所以我会马上出来说。这是我第一次创建 IDisposable 类,我想确保我正确地创建了我的类,正确地调用它,并正确地处理它。谢谢!

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 命名空间爬虫 类 LoggingClass 公共类 LoggingDisposeable : IDisposable public void GenericLogging(string systemMsg, string SystemClass, string SystemSection, string ID, string FixID, string baseURL, string mysqlQueryName, string mysqlQuery) 字符串 Loggingall = " 插入 tblLogs " + "set SystemMsg='" + systemMsg.Replace("'", "''") + "'" + ",SystemClass = '" + SystemClass.Replace("'", "''") + "'" + ",SystemSection = '" + SystemSection.Replace("'", "''") + ",ID = '" + CarID.Replace("'", "''") + "'" + ",FixID = '" + FixID.Replace("'", "''") + "'" + ",baseurl = '" + baseURL.Replace("'", "''") + "'" + ",mysqlqueryName = '" + mysqlQuery.Replace("'", "''") + ",mysqlquery = '" + mysqlQuery.Replace("'", "''") + "'" + ",Site = '自动交易者'" + ",TimeStamp = Now()"; 使用 (var MYSQLP = new MySQLProcessing.MySQLProcessor()) MYSQLP.MySQLInsertUpdate(Loggingall, "Loggingall"); 公共无效处置() this.Dispose(true); GC.SuppressFinalize(this); protected virtual void Dispose(bool disposing) if (!this.Disposed) 如果(处置) // 在此处执行托管清理。 // 在此处执行非托管清理。 this.Disposed = true; 受保护的布尔处置得到;私人套装;

这就是我所说的。

 var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 5;
                Parallel.ForEach(urlTable.AsEnumerable(),options, drow =>
            

 using (var logClass = new LoggingClass.LoggingDisposeable())
                                
                                    logClass.GenericLogging("ZipCode not available for this dealerL", "DealershipRequest", "checkExistingDealers", dealerID, "DealerShipZipCode",rDealerLink, "", "");

</pre>

【问题讨论】:

你不需要在这个类上实现 IDisposable...你没有处理任何东西。 @EricDahlvang 这存在于并行 foreach 循环中,我称之为此类,请参阅编辑 您为什么要部分实现 Microsoft 仅在处理非托管资源时推荐的 finalize 模式?您应该正确实现它或根本不实现它。 @ChaosPandion 主要原因是因为老实说我对如何构建/使用 IDisposable 并不积极 using () blocks internally 当代码存在块时调用Dispose(),因此您的资源已经在此方法中被处置,因为您已经发布它并且您没有'不需要单独实现IDisposable 【参考方案1】:

我认为你打算做的是这样的:

public class LoggingDisposeable : IDisposable

    MySQLProcessing MySQLP;

    public LoggingDisposeable()
    
        MYSQLP = new MySQLProcessing.MySQLProcessor();
    

    public void GenericLogging(string systemMsg, string SystemClass, string SystemSection, string ID, string FixID, string baseURL, string mysqlQueryName, string mysqlQuery)
    
        string Loggingall = " insert into tblLogs " +
                        "set SystemMsg='" + systemMsg.Replace("'", "''") + "'" +
                        ",SystemClass = '" + SystemClass.Replace("'", "''") + "'" +
                        ",SystemSection = '" + SystemSection.Replace("'", "''") +
                        ",ID = '" + CarID.Replace("'", "''") + "'" +
                        ",FixID = '" + FixID.Replace("'", "''") + "'" +
                        ",baseurl = '" + baseURL.Replace("'", "''") + "'" +
                        ",mysqlqueryName = '" + mysqlQuery.Replace("'", "''") +
                        ",mysqlquery = '" + mysqlQuery.Replace("'", "''") + "'" +
                        ",Site = 'AutoTrader'" +
                        ",TimeStamp = Now()";

            MYSQLP.MySQLInsertUpdate(Loggingall, "Loggingall");                
    

    public void Dispose()
    
        MYSQLP.Dispose();
    

然后像这样使用它:

using (var logClass = new LoggingDisposeable())

    var options = new ParallelOptions();
    options.MaxDegreeOfParallelism = 5;
    Parallel.ForEach(urlTable.AsEnumerable(), options, drow =>
        
            logClass.GenericLogging("ZipCode not available for this dealerL", "DealershipRequest", "checkExistingDealers", dealerID, "DealerShipZipCode", rDealerLink, "", "");
        );

【讨论】:

不,当你使用 using 语句时会自动调用:msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx 在您的示例中,您创建 public LoggingDisposeable() MYSQLP = new MySQLProcessing.MySQLProcessor(); 但从不调用它,在这一点上它没有意义吗? @EricDahlvang 由于命名空间 MySQLProcessing.MySQLProcessor MySQLP,我也不得不对此进行修改; 它在构造函数中......当您通过调用 new LoggingDisposeable() 创建类时被调用。了解其工作原理的最佳方法是在所有地方放置断点,并逐步执行代码。 那么我为什么不这样做呢?类 LoggingClass : IDisposable MySQLProcessing.MySQLProcessor MySQLP = new MySQLProcessing.MySQLProcessor();

以上是关于C# IDisposable 正确用法和调用的主要内容,如果未能解决你的问题,请参考以下文章

C# IDisposable 类,正确使用 Dispose,获取错误“dispose”需要 1 个参数

C#中IDisposable的用法

C#中的IDisposable模式用法详解

C#中的IDisposable模式用法详解

从组件派生并正确实现 IDisposable

c# 中using 关键字有哪些用法?