我从阅读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在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?
为什么有些人在Finalize方法上使用该Dispose方法?
在什么情况下你会使用Finalize方法而不是Dispose方法,反之亦然?
例如:
public class Person
{
public Person()
{
}
~Person()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我什么时候应该手动创建析构函数?什么时候需要创建析构函数?
我认为如果您的程序没有,GC会最终调用Dispose,但是您应该在程序中调用Dispose()以使清除确定性.
但是,从我的小测试程序来看,我根本没有看到Dispose被调用....
public class Test : IDisposable
{
static void Main(string[] args)
{
Test s = new Test();
s = null;
GC.Collect();
Console.ReadLine();
}
public Test()
{
Console.WriteLine("Constructor");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
}
Run Code Online (Sandbox Code Playgroud)
//输出只是"构造函数",我没有像我期望的那样得到"Dispose".这是怎么回事?
编辑:是的,我知道我应该调用Dispose() - 我在使用一次性物体时遵循标准模式.我的问题出现了,因为我试图追踪某些elses代码的漏洞,这是托管C++(另一层复杂性,这将是另一个线程的好主题).
我很困惑处置.我正在尝试让我的代码正确处理资源.所以我一直在将我的类设置为IDisposable(使用Dispose方法),确保调用Dispose方法.
但是现在FXCop告诉我很多关于Disposing = false和调用Dispose(false)的东西.
我没有看到一个带有bool的Dispose方法.我需要制作一个吗?如果是这样,为什么?为什么不在处理时调用一个方法呢?
我在这里看到了一些代码:http://msdn.microsoft.com/en-us/library/ms244737.aspx,它展示了如何制作一个带有bool的Disposing方法.它表示它适用于本地和管理资源. 但我认为处理的全部内容仅适用于非管理资源.
此外,FXCop抱怨的路线是这样的:
~OwnerDrawnPanel()
{
_font.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
它说:
CA1063:Microsoft.Design:修改'OwnerDrawnPanel .~ OwnerDrawnPanel()',以便它调用Dispose(false)然后返回.
但是Font上没有Dispose(bool)(我能找到).
为什么我需要Dispose(bool)?如果我这样做,为什么Font没有呢?因为它没有它,为什么FXCop要求我使用它?
感谢所有的好答案.我想我现在明白了.这是
处置"非管理"资源分为两类:
Dispose(bool)用于表示两者之间的区别:
我是C#的新手,如果这是一个明显的问题,请道歉.
在MSDN Dispose示例中,它们定义的Dispose方法是非虚拟的.这是为什么?这对我来说似乎很奇怪 - 我希望IDisposable的子类具有自己的非托管资源,它只会覆盖Dispose并在自己的方法底部调用base.Dispose().
谢谢!
所以,我有一个从WCF服务公开的方法:
public GetAllCommentsResponse GetAllComments(GetAllCommentsRequest request)
{
var response = new GetAllCommentsResponse();
using(_unitOfWork)
try
{
Guard.ArgNotNull(request, "request");
var results = _unitOfWork.CommentRepository.Get(d => d.Id > 0).ToArray();
//... Do rest of stuff here
}
catch (Exception ex)
{
response.Success = false;
response.FailureInformation = ex.Message;
Logger.LogError("GetAllComments Method Failed", ex);
}
return response;
}
Run Code Online (Sandbox Code Playgroud)
我有一个全局DataUnitOfWork对象(实现IDisposable),当服务调用进来时,Ninject通过构造函数参数实例化.当调试时,如果我使用
using(_unitOfWork)
Run Code Online (Sandbox Code Playgroud)
超出范围后,_unitOfWork对象立即被释放,然后被Ninject再次调用(尽管它被标记为已丢弃,因此没有任何反应.)如果没有using语句,Ninject将处理处理.
长话短说,这是否有一般的经验法则?在我阅读的所有内容似乎表明永远不会使用它,或者在某些折衷的情况下使用它之后,我一直害怕整个IDisposable的东西,但它总是让我感到困惑.
任何输入都表示赞赏.
哦,当我在这里打字时,为什么在处理时确实有GC.SuppressFinalize()的调用?Dispose和Finalize有何不同?
请考虑以下代码:
namespace DisposeTest
{
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Calling Test");
Test();
Console.WriteLine("Call to Test done");
}
static void Test()
{
DisposeImplementation di = new DisposeImplementation();
}
}
internal class DisposeImplementation : IDisposable
{
~DisposeImplementation()
{
Console.WriteLine("~ in DisposeImplementation instance called");
}
public void Dispose()
{
Console.WriteLine("Dispose in DisposeImplementation instance called");
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使我在Test();调用之后放置了一个等待循环,Dispose也永远不会被调用.所以这很糟糕.我想编写一个简单易用的类,以确保清理所有可能的资源.我不想把这个责任交给我班级的用户.
可能的解决方案:使用using或调用自己处理(基本相同).我可以强制用户使用吗?或者我可以强制调用处理吗?
呼叫GC.Collect();后Test();也不起作用.
把di以null不调用任何处置.解构器可以工作,因此对象在退出时会被解构Test()
好的,现在很清楚!
谢谢大家的答案!我会在评论中添加警告!
我知道C#可以通过垃圾收集器很好地管理资源.但既然它有,那究竟是什么,为什么需要呢?
任何人都可以解释为什么.Dispose()在asp.net mvc中需要?
另外,处理连接意味着什么?为什么需要?任何人都知道为什么处理数据库连接很重要的复杂性db.Dispose()?这与EF相关,还是与SQL Server相关?我想知道为什么.
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
Run Code Online (Sandbox Code Playgroud) c# asp.net-mvc garbage-collection entity-framework idisposable
我有几个问题,我无法得到正确的答案.
1)当我们没有析构函数时,为什么我们应该在Dispose函数中调用SuppressFinalize.
2)Dispose和finalize用于在对象被垃圾收集之前释放资源.无论是托管资源还是非托管资源我们都需要释放它,那么为什么我们需要在dispose函数中使用一个条件,当我们从IDisposable调用这个重写函数时传递'true':从finalize调用时Dispose并传递false.
请参阅我从网上复制的以下代码.
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我删除布尔保护的Dispose函数并实现如下所示.
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose();
}
public void Dispose()
{
// Code …Run Code Online (Sandbox Code Playgroud) c# ×10
.net ×6
dispose ×5
idisposable ×5
asp.net-mvc ×1
destructor ×1
finalizer ×1
memory ×1
ninject ×1