5

我正在使用Memory Managementwhile 返回如下数据。

private DataSet ReturnDs()
{
    using (DataSet ds = new DataSet())
    {
        return ds;
    }
}

查询- 在返回数据时放置“使用”语句是否有任何问题?我仍然得到完整的模式以及接收函数中的数据?

4

5 回答 5

4

这绝对是一个错误的模式。它现在为您工作的唯一原因是它DataSet.Dispose()实际上是一个假人。

using (DataSet ds = new DataSet())
{
    return ds;
}  // there is a ds.Dispose() here but it does nothing.

如果您将 DataSet 替换为例如 Enitity 框架 DbContext,那么您将不会在调用函数中看到任何数据。

于 2012-08-05T11:25:55.110 回答
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;
}

以确保在故障情况下正确处置对象。

于 2012-08-05T11:26:40.397 回答
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 对象,处理对您的应用程序至关重要的东西,那么您的工作代码将突然停止工作。

于 2012-08-05T11:23:56.373 回答
0

我不确定你的问题到底是什么。

一旦方法通过返回某些东西结束,ds.Dispose()将自动被调用。

这意味着您的方法返回的 DataSet 将在您的调用方法接收到它时被释放。

于 2012-08-05T11:21:31.080 回答
0

作为 Mert 评论,请注意您正在处理要返回的对象。但基本上, using 实际上是一个 try/finally 并且 dispose 将被称为方法返回。效果取决于每种类型的 IDisposable 实现。通常,您不应该处置(杀死)您返回给可能会使用它的调用者的实体。

于 2012-08-05T11:23:24.517 回答