我从阅读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在上面的代码中包含了一百万个字符串,并且你想现在释放那个内存,而不是等待垃圾收集器.上面的代码会实现吗?
它需要分配哪些非托管资源?它不仅仅是一个简单的托管数据阵列吗?那么为什么要处置呢?
我最近被要求协助其他团队建立ASP .NET网站.他们已经编写了大量的代码 - 我被特别要求为该网站构建一些单独的页面.
在探索网站其余部分的代码时,正在构建的DataTables的数量向我跳出来.作为一个相对较新的领域,我从来没有像使用这个网站那样使用数据库的应用程序,所以我不确定这是多么常见.似乎每当从我们的数据库查询数据时,结果都存储在DataTable中.然后,此DataTable通常自行传递,或者传递给构造函数.使用DataTable初始化的类始终将DataTable 分配给私有/受保护字段,但是这些类中只有少数实现IDisposable.实际上,到目前为止我浏览过的数千行代码中,我还没有看到在DataTable上调用Dispose方法.
如果有的话,这似乎不是好的OOP.这是我应该担心的吗?或者我只是比我更注重细节?假设您是最有经验的开发人员,如果刚刚被指派帮助您访问您网站的人向您询问此"问题",您会有什么感受或反应?
我已经看到了使用一次性对象内联,所以很多时候开发商这里的实例.内联我的意思是:
var result = new DataTable().Compute("1 + 4 * 7", null);
Run Code Online (Sandbox Code Playgroud)
我知道该Dispose方法不会被调用,但由于没有对该对象进行引用,垃圾收集器将如何处理它?使用像这样的一次性物体是否安全?
我DataTable在我的例子中使用了一个,因为它是我找到的唯一具体例子,但我的问题一般适用于一次性物品.我不是那样亲自使用它们,我只是想知道如果它们以这种方式使用它们是否由GC处理它们.
我通过非常简单的代码进行研究,并且一直看到数据表的dispose()结果
以下是代码
DataTable dt= new Datatable();
SqlCommand Cmd = new SqlCommand("sp_getData",SqlCon);
SqlCommand.CommandType= CommandType.StroedProcedure;
SqlCon.Open();
sqlDataReader dr= cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource =dt;
dt.Dispose() // Here I dispose the table as it is no use for me & wanna memory free from this
Run Code Online (Sandbox Code Playgroud)
但在处理掉数据表之后我仍然发现它仍然显示RowCount = 10k.
Dispose()方法是不是释放内存并使对象为null?
我怎样才能使它成为null或释放这个对象占用的内存?
前几天在代码审查期间出现了一个关于 using 块应该多快关闭的问题。一个阵营说,“一旦你完成了对象”;另一个,“在它超出范围之前的某个时间”。
在这个特定的例子中,有一个 DataTable 和一个 SqlCommand 对象要处理。我们需要在单个语句中引用两者,并且需要迭代 DataTable。
营地1:
List<MyObject> listToReturn = new List<MyObject>();
DataTable dt = null;
try
{
using (InHouseDataAdapter inHouseDataAdapter = new InHouseDataAdapter())
using (SqlCommand cmd = new SqlCommand())
{
dt = inHouseDataAdapter.GetDataTable(cmd);
}
foreach (DataRow dr in dt.Rows)
{
listToReturn.Add(new MyObject(dr));
}
}
finally
{
if (dt != null)
{
dt.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
推理:在使用完 SqlCommand 后立即处理它。不要在另一个对象的 using 块中开始可能很长的操作,例如迭代表。
营地2:
List<MyObject> listToReturn = new List<MyObject>();
using (InHouseDataAdapter inHouseDataAdapter = new InHouseDataAdapter())
using (SqlCommand cmd = new …Run Code Online (Sandbox Code Playgroud) 我想了解它们之间的区别
public DataTable ExectNonActQuery(string spname, SqlCommand command)
{
using (DataTable dt = new DataTable())
{
cmd = command;
cmd.Connection = GetConnection();
cmd.CommandText = spname;
cmd.CommandType = CommandType.StoredProcedure;
da.SelectCommand = cmd;
da.Fill(dt);
return (dt);
}
}
Run Code Online (Sandbox Code Playgroud)
和
public DataTable ExectNonActQuery(string spname, SqlCommand command)
{
DataTable dt = new DataTable();
cmd = command;
cmd.Connection = GetConnection();
cmd.CommandText = spname;
cmd.CommandType = CommandType.StoredProcedure;
da.SelectCommand = cmd;
da.Fill(dt);
return (dt);
}
}
Run Code Online (Sandbox Code Playgroud)
我实际上想要了解使用"使用"创建新对象的好处,而不是像这样直接创建它
DataTable dt = new DataTable();
Run Code Online (Sandbox Code Playgroud) 我正在使用Memory Managementwhile返回如下数据.
private DataSet ReturnDs()
{
using (DataSet ds = new DataSet())
{
return ds;
}
}
Run Code Online (Sandbox Code Playgroud)
查询 - 在返回数据时放置"使用"语句是否有任何问题?我仍在获取完整的架构以及接收函数中的数据?
例如:
Queue<System.Drawing.SolidBrush> brushQ = new Queue<System.Drawing.SolidBrush>();
...
brushQ.Clear();
Run Code Online (Sandbox Code Playgroud)
如果我没有明确地将每个项目出列并单独处理它们,那么在调用Clear()时是否会处理剩余的项目?队列被垃圾收集时怎么样?
假设答案是"不",那么最佳做法是什么?您是否必须始终遍历队列并处理每个项目?
这可能会变得很难看,特别是如果你必须尝试..最终围绕每个dispose,以防万一抛出异常.
编辑
因此,对于通用集合的用户而言,如果项目是Disposable(意味着他们可能正在使用不会被垃圾收集器清理的非托管资源),那么似乎负担很重,那么:
也许通用集合的文档应该提到这一点.