我正在使用Memory Management
,同时返回如下数据。
private DataSet ReturnDs()
{
using (DataSet ds = new DataSet())
{
return ds;
}
}
查询 - 在返回数据时放置'使用'语句是否有任何问题?我还在获取完整的架构以及接收函数中的数据吗?
答案 0 :(得分:4)
这绝对是一种错误的模式。它现在为你工作的唯一原因是DataSet.Dispose()
实际上是假的。
using (DataSet ds = new DataSet())
{
return ds;
} // there is a ds.Dispose() here but it does nothing.
如果用例如Enitity框架DbContext替换DataSet,那么您将不会在调用函数中看到任何数据。
答案 1 :(得分:4)
一般而言,处理您要返回的对象是一个错误:您的代码尚未完成该对象,并且您将把一个损坏的对象交给调用者。
确实如此:不要Dispose()
,这意味着:不要在将要返回的对象上使用using
。由打电话者来处理它:他们现在是所有者。当然,理想情况下应该在API中记录。
但更普遍的是,您还需要考虑例外情况。如果您的方法错误会怎样?对于复杂场景,您可能需要以下内容:
SomeType foo = null;
try {
// initialize and populate foo - this could error half-way through
return foo;
} catch {
if(foo != null) foo.Dispose();
throw;
}
确保在失败的情况下正确放置对象。
答案 2 :(得分:2)
在调用方法中使用using
语句,而不是返回对象的方法。
public void Caller()
{
using(DataSet ds = GetDataSet())
{
// code here
}
}
public DataSet GetDataSet()
{
// don't use a using statement here
return ds;
}
using
语句与执行此操作基本相同:
DataSet ds = null;
try
{
// code here
}
finally
{
if(ds != null)
{
ds.Dispose();
ds = null;
}
}
因此,如果在一个应该在using
语句中返回对象的方法中使用using
语句,它将返回一个Disposed对象(即封闭流,闭合数据集等)。 ..)这意味着一些内部对象可以为null或关闭。换句话说,所有内部资源都将被清理,这是首先实现IDisposable的目的。如果您的应用程序依赖某些内部资源可用,例如在使用Stream对象时,它将引发异常。
另请注意,并非所有finally
块都写相同。请记住,实现了IDispoable来清理任何INTERNAL资源和非托管对象。在using
语句之外可能不需要这些内部资源,因此有时使用using
语句可能看起来工作正常但不建议这样做,并且肯定不能用于所有对象。如果Microsoft决定在将来的版本中更改DataSet对象,处理对您的应用程序至关重要的内容,那么您的工作代码将突然停止工作。
答案 3 :(得分:0)
我不确定你的问题到底是什么。
一旦方法通过重新调整某事结束,将自动调用ds.Dispose()
。
这意味着当您的调用方法接收到时,您的方法返回的DataSet将被处理掉。
答案 4 :(得分:0)
作为Mert评论,请注意您正在处理您返回的对象。 但基本上,使用实际上是一个try / finally,并且dispose将被称为方法返回。效果取决于每种类型的IDisposable实现。通常情况下,你不应该处置(杀死)你可能会使用它的那个你回来的实体。