标签: idisposable

正确使用IDisposable接口

我从阅读MSDN文档中了解到,IDisposable接口的"主要"用途是清理非托管资源.

对我来说,"非托管"意味着数据库连接,套接字,窗口句柄等等.但是,我已经看到了Dispose()实现该方法以释放托管资源的代码,这对我来说似乎是多余的,因为垃圾收集器应该照顾那对你而言.

例如:

public class MyCollection : IDisposable
{
    private List<String> _theList = new List<String>();
    private Dictionary<String, Point> _theDict = new Dictionary<String, Point>();

    // Die, clear it up! (free unmanaged resources)
    public void Dispose()
    {
        _theList.clear();
        _theDict.clear();
        _theList = null;
        _theDict = null;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是否使得垃圾收集器可以使用的内存MyCollection比通常更快?

编辑:到目前为止,人们已经发布了一些使用IDisposable清理非托管资源(例如数据库连接和位图)的好例子.但是假设_theList在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?

.net c# garbage-collection idisposable

1586
推荐指数
12
解决办法
31万
查看次数

在C#中完成/处理模式

C#2008

我一直在研究这个问题,我仍然对一些问题感到困惑.我的问题如下

  1. 我知道如果你处理非托管资源,你只需要一个终结器.但是,如果您使用托管资源来调用非托管资源,您是否仍需要实现终结器?

  2. 但是,如果您开发一个不直接或间接使用任何非托管资源的类,您是否可以实现IDisposable该类,以便您的类的客户端可以使用'using statement'?

    是否可以接受实现IDisposable,以便您的类的客户端可以使用using语句?

    using(myClass objClass = new myClass())
    {
        // Do stuff here
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我在下面开发了这个简单的代码来演示Finalize/dispose模式:

    public class NoGateway : IDisposable
    {
        private WebClient wc = null;
    
        public NoGateway()
        {
            wc = new WebClient();
            wc.DownloadStringCompleted += wc_DownloadStringCompleted;
        }
    
    
        // Start the Async call to find if NoGateway is true or false
        public void NoGatewayStatus()
        {
            // Start the Async's download
                // Do other work here
            wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
        }
    
        private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // …
    Run Code Online (Sandbox Code Playgroud)

.net c# idisposable finalizer

369
推荐指数
7
解决办法
17万
查看次数

是否必须处理HttpClient和HttpClientHandler?

.NET Framework 4.5中的System.Net.Http.HttpClientSystem.Net.Http.HttpClientHandler实现了IDisposable(通过System.Net.Http.HttpMessageInvoker).

using声明文件说:

通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它.

这个答案使用了这种模式:

var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("foo", "bar"),
        new KeyValuePair<string, string>("baz", "bazinga"),
    });
    cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
    var result = client.PostAsync("/test", content).Result;
    result.EnsureSuccessStatusCode();
}
Run Code Online (Sandbox Code Playgroud)

但是微软最明显的例子并没有Dispose()明确地或隐含地调用.例如:

c# idisposable using .net-4.5 dotnet-httpclient

315
推荐指数
7
解决办法
12万
查看次数

我什么时候应该使用GC.SuppressFinalize()?

在.NET中,我应该在哪种情况下使用GC.SuppressFinalize()

使用这种方法有什么好处?

.net c# garbage-collection idisposable suppressfinalize

274
推荐指数
3
解决办法
10万
查看次数

我应该Dispose()DataSet和DataTable吗?

DataSet和DataTable都实现了IDisposable,因此,通过传统的最佳实践,我应该调用它们的Dispose()方法.

但是,从我到目前为止所读到的,DataSet和DataTable实际上并没有任何非托管资源,因此Dispose()实际上并没有做太多.

另外,我不能只使用,using(DataSet myDataSet...)因为DataSet有一组DataTables.

所以,为了安全起见,我需要遍历myDataSet.Tables,处理每个DataTable,然后处理DataSet.

那么,在我的所有DataSet和DataTables上调用Dispose()是否值得麻烦?

附录:

对于那些认为应该处理DataSet的人:通常,处理的模式是使用usingor try..finally,因为你想保证将调用Dispose().

然而,这对于一个集合来说真的很快.例如,如果对Dispose()的一个调用抛出异常,你会怎么做?你吞下它(这是"坏"),以便你可以继续处理下一个元素?

或者,你是否建议我只调用myDataSet.Dispose(),而忘记在myDataSet.Tables中处理DataTables?

datatable dispose idisposable using dataset

187
推荐指数
7
解决办法
10万
查看次数

在使用块的中间返回

就像是:

using (IDisposable disposable = GetSomeDisposable())
{
    //.....
    //......
    return Stg();
}
Run Code Online (Sandbox Code Playgroud)

我相信这不是回报声明的合适地方,是吗?

c# dispose idisposable using-statement

183
推荐指数
6
解决办法
4万
查看次数

使用带有null对象的语句

using在(可能)null对象上使用该语句是否安全?
请考虑以下示例:

class Test {
    IDisposable GetObject(string name) {
        // returns null if not found
    }

    void DoSomething() {
        using (IDisposable x = GetObject("invalid name")) {
            if (x != null) {
                 // etc...
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否保证Dispose只有在对象不为空时才会被调用,而且我不会得到一个NullReferenceException

c# idisposable using

168
推荐指数
3
解决办法
3万
查看次数

我应该为流对象调用Close()或Dispose()吗?

类如Stream,StreamReader,StreamWriter等工具IDisposable界面.这意味着,我们可以Dispose()在这些类的对象上调用方法.他们还定义了一个public名为的方法Close().现在让我感到困惑的是,一旦我完成了对象,我该怎么称呼?如果我同时打电话怎么办?

我目前的代码是这样的:

using (Stream responseStream = response.GetResponseStream())
{
   using (StreamReader reader = new StreamReader(responseStream))
   {
      using (StreamWriter writer = new StreamWriter(filename))
      {
         int chunkSize = 1024;
         while (!reader.EndOfStream)
         {
            char[] buffer = new char[chunkSize];
            int count = reader.Read(buffer, 0, chunkSize);
            if (count != 0)
            {
               writer.Write(buffer, 0, count);
            }
         }
         writer.Close();
      }
      reader.Close();
   }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我编写了using()构造,自动调用Dispose()每个对象的方法.但我也称之为Close()方法.这样对吗?

请告诉我使用流对象时的最佳做法.:-)

MSDN示例不使用using()构造,并且调用 …

c# idisposable stream streamwriter streamreader

139
推荐指数
6
解决办法
12万
查看次数

你如何防止IDisposable传播到你的所有课程?

从这些简单的类开始......

假设我有一组这样简单的类:

class Bus
{
    Driver busDriver = new Driver();
}

class Driver
{
    Shoe[] shoes = { new Shoe(), new Shoe() };
}

class Shoe
{
    Shoelace lace = new Shoelace();
}

class Shoelace
{
    bool tied = false;
}
Run Code Online (Sandbox Code Playgroud)

A Bus有一个Driver,Driver有两个Shoe,每个Shoe有一个Shoelace.一切都很傻.

将一个IDisposable对象添加到Shoelace

后来我决定对它进行一些操作Shoelace可能是多线程的,所以我添加了一个EventWaitHandle用于与之通信的线程.所以Shoelace现在看起来像这样:

class Shoelace
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;
    // ... other stuff .. …
Run Code Online (Sandbox Code Playgroud)

.net c# garbage-collection dispose idisposable

137
推荐指数
3
解决办法
7614
查看次数

垃圾收集器是否会为我调用IDisposable.Dispose?

.NET IDisposable Pattern 意味着如果您编写终结器并实现IDisposable,则终结器需要显式调用Dispose.这是合乎逻辑的,而且在极少数情况下我总是会做终结器的保证.

但是,如果我这样做会发生什么:

class Foo : IDisposable
{
     public void Dispose(){ CloseSomeHandle(); }
}
Run Code Online (Sandbox Code Playgroud)

并且不要实现终结器或任何东西.框架会为我调用Dispose方法吗?

是的,我意识到这听起来很愚蠢,而且所有的逻辑都暗示它不会,但我总是有两件事让我不确定.

  1. 几年前有人曾告诉我,事实上它会这样做,而且那个人有"非常了解他们的东西"的良好记录.

  2. 编译器/框架根据您实现的接口(例如:foreach,扩展方法,基于属性的序列化等)执行其他"神奇"操作,因此这也可能是"魔术".

虽然我已经阅读了很多关于它的内容,并且有很多暗示的内容,但我从来没有能够找到这个问题的肯定是或否答案.

.net dispose idisposable

126
推荐指数
5
解决办法
3万
查看次数