5

Memory Management以下のようなデータを返しながらwhileを使用しています。

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

クエリ-データを返すときに「Using」ステートメントを配置することに問題はありますか?受信関数のデータだけでなく、完全なスキーマをまだ取得していますか?

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は、内部リソースとアンマネージドオブジェクトをクリーンアップするために実装されたことを忘れないでください。これらの内部リソースはステートメントの外部では必要ない場合があるusingため、ステートメントをそのまま使用usingすると正しく機能するように見える場合がありますが、推奨されておらず、すべてのオブジェクトで確実に機能するとは限りません。Microsoftが将来のリリースでDataSetオブジェクトを変更し、アプリケーションに不可欠なものを破棄することを決定した場合、動作中のコードは突然動作を停止します。

于 2012-08-05T11:23:56.373 に答える
0

あなたの質問が正確に何であるかわかりません。

メソッドが何かを再調整して終了すると、ds.Dispose()が自動的に呼び出されます。

これは、メソッドが返すDataSetは、呼び出し元のメソッドがそれを受け取ったときにすでに破棄されていることを意味します。

于 2012-08-05T11:21:31.080 に答える
0

Mertのコメントとして、返されるオブジェクトを破棄していることに注意してください。ただし、基本的に、使用は実際にはtry / finalであり、disposeはメソッドreturnと呼ばれます。効果は、各タイプのIDisposable実装によって異なります。通常、呼び出し元に返すエンティティを破棄(強制終了)して、おそらくそれを使用することは想定されていません。

于 2012-08-05T11:23:24.517 に答える