我需要使用IDisposable吗?

时间:2017-05-26 19:52:24

标签: c# garbage-collection

试着看看我是否正确理解了这一点。遗憾的是,我对IDisposable没有多少经验。我们采用静态类并使其成为非静态类,它是一个负责在我们的Xamarin应用程序中进行Web服务调用的类。这是一个我绝对不想躺在那里的物体。所以我想让这个类继承IDisposable接口,并实现了如下所示的方法:

private bool disposedValue = false; // To detect redundant calls

protected virtual void Dispose(bool disposing)
{
    if (!disposedValue)
    {
        if (disposing)
        {
            // TODO: dispose managed state (managed objects).
        }

        // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
        // TODO: set large fields to null.

        disposedValue = true;
    }
}

// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
//~WebServiceCallThread()
//{
//    // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
//    Dispose(false);
//}

// This code added to correctly implement the disposable pattern.
public void Dispose()
{
    // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    Dispose(true);
    // TODO: uncomment the following line if the finalizer is overridden above.
    //GC.SuppressFinalize(this);
}

所有这一切似乎都在做,就是在调用Dispose方法时,它会调用在Dispose(bool disposing)之上声明的虚方法。使用当前代码,这不会做任何事情(或者看起来如此)。它只调用Dispose方法,在该方法中调用重载的Dispose方法。但实际上并没有什么"处理"这里。

经过一些研究,它是SEEMS(这就是为什么我要问,我认为我正确理解)。如果您finalizer,它只会调用GC.SuppressFinalizedispose managed state方法。我不确定dispose manage state是什么意思,但我班上真的没什么需要处理的。我只是有一些全局的int变量,但就是这样。这个类的内容是一个HttpCall,它已经自动处理了这些对象,如下所示:

public async void CallUrlHttpClient(string URL, System.Action<string> Handler, System.Action<XamarinMobile.Classes.ErrorInfo> ErrorHandler, int Tries)
        {
            var result = string.Empty;
            didMakeSuccessfulHttpRequest = false;

            using (var client = new HttpClient())
            {
               ... Code
            }
            ...

所以,我的问题是:我是否需要让这个类继承IDisposable?我想知道是否有任何事情要做,但似乎我的应用程序可以利用GC来摆脱我使用这个类的对象。这就是我通过类中的静态方法调用它的方法:

    public static void WebServiceCall(string URL, System.Action<string> Callback)
    {
        //using (XamarinMobile.Classes.WebServiceCallThread thread = new Classes.WebServiceCallThread())
        //{
        XamarinMobile.Classes.WebServiceCallThread thread = new Classes.WebServiceCallThread();
        thread.Call(URL, Callback);
        //} 
    }

如果我正确理解GC,一旦完成此方法,GC将自动删除该对象。那么我真的需要从IDisposable继承WebServiceCallThread吗?我再次问我是否正确理解了这一切。如果没有,请纠正我,让我知道我在哪里感到困惑。

感谢。

1 个答案:

答案 0 :(得分:2)

如果您的类创建了HttpClient并在其整个生命周期内维护该实例(如实例变量),那么您将实现IDisposable,并且您的Dispose()方法将处置HttpClient 1}}。

这就是这部分:

if (disposing)
{
    // TODO: dispose managed state (managed objects).
    _httpClient.Dispose();
}

在这种情况下,您不需要实施IDisposable,因为您已经处置了HttpClient

        using (var client = new HttpClient())
        {
           ... Code
        }

但是,它actually recommended为每个端点创建一个HttpClient实例并重复使用它,而不是反复创建和处理。 (如果您的负载不是很重,那么您可能无法通过创建和处置HttpClient来看到任何不良影响。)

如果您想避免创建和处置HttpClient,那么您可以实施IDisposable。您的类要么创建或接收(在其构造函数中)HttpClient的实例。现在你的班级&#34;拥有&#34;在您的课程被处理时需要处理的那个实例,您可以创建课程IDisposable。这样其他人就知道你的班级需要处理。他们可能不知道为什么,但这并不重要。通过制作IDisposable,您可以让他们知道他们需要处理它。然后当你的课被处理时,它会清理它的HttpClient

只是提供一点额外的澄清:

很多人,如果被问到&#34;什么是IDisposable?&#34;会回答它导致垃圾收集。它实际上与垃圾收集无关。当对象超出范围(不再有对它们的引用)时,对象总是被垃圾收集,无论它们是否实现IDisposable

出现混乱,因为IDisposable(您引用的)的推荐模式包括终结器(~WebServiceCallThread()),当对象被垃圾回收时调用该模式。

当垃圾收集器删除一个项目时,它会调用终结器(如果有的话)。这种模式会导致终结器调用Dispose(),如果它还没有被调用,就像有人没有像他们应该调用Dispose()一样备份。但它无法替代呼叫Dispose(),因为没有人知道垃圾收集器何时收集该项目。终结者永远不会被召唤。如果消费者不打电话给Dispose(),它只是一个备用手段,可以减轻所发生的情况。