0

変数を定義し、変数にスペースを割り当て、変数を初期化し、すべてを適切にクリーンアップする場合の C# での優れたプログラミング方法についてアドバイスをお願いします。

私が現在直面している問題は、アンマネージ API 関数を使用する関数があり、その結果、アンマネージ メモリにもアクセスすることです (マーシャリングが使用されます)。関数をきれいにして、終了する前にすべてを適切に破棄したいと思います。ただし、実際の作業はすべてtry-catchブロック内で行われます。つまり、 catchまたはfinallyブロックですべてをクリーンアップすることはできません。

私が行ったことは、すべての変数を宣言し、それらのためにメモリを予約し、関数に入った直後にそれらを初期化し、最後にブロックですべてをクリーンアップ (ハンドルを閉じる、メモリを解放するなど) することです。

すべて問題ありませんが、 tryブロックで変数の宣言、初期化、およびメモリの割り当てを行いたいと思います(たとえば、配列を初期化するときや、メモリにスペースを割り当てるとき、または神がどこにあるかを知っているときにも問題が発生する可能性があります)。頭に浮かぶ唯一のことは、2 つのtry-catchブロックをネストすることです。これでよろしいですか、それとも別の提案をしていただけますか?

これが私がこれまでに持っているものです:

//Declare variables, allocate memory, initialize variables.
........
try
{
    //Do actual work - write to file and read from a file in my case
    .........
}
catch (Exception exc)
{
    //Exception handler for file write/read errors
}
finally
{
    //Clean up (release handles, free memory,...)
}

そして、ここに私が考えていることがあります:

try
{
   //Declare variables, allocate memory, initialize variables.
   ........
   try
   {
       //Do actual work - write to file and read from a file in my case
       .........
   }
   catch (Exception exc)
   {
       //Exception handler for file write/read errors
   }
}
catch (Exception exc_1)
{
    //Exception handler for variable declaration, initialization, memory allocation errors
}
finally
{
    //Clean up (release handles, free memory,...)
}

ご協力いただきありがとうございます。

乾杯!

4

4 に答える 4

1

IDisposableDispose メソッドを呼び出すためのインターフェイスを実装できます。

または、ブロックを使用するベスト プラクティスとしてusing

using (var variable = .....)
{

 ...

}

ブロックを使用する特殊性は、処理の最後に Dispose メソッドを呼び出すことです。

たとえば、使用する場合SqlConnection

var(var connection = new SqlConnection("...."))
{
....

}

このコードだけで十分です

リンク: http://msdn.microsoft.com/fr-fr/library/vstudio/system.idisposable.aspx

リンク: http://msdn.microsoft.com/fr-fr/library/yh598w02%28v=vs.80%29.aspx

于 2012-09-08T12:50:09.717 に答える
0

そのアプローチの問題は可変であり、finally(およびcatch)では範囲外です

    try
    {
        string testString;
    }
    catch (Exception ex)
    {
    }
    finally
    {
        // testString is not in scope
    }

あなたの懸念は、宣言が実行時エラーをスローするかもしれないということですか?

コメントに基づいて、OPは初期化を宣言と分離できることを認識していません。

    List<string>  testLString;        
    try
    {
        testLString = new List<string>();
    }
    catch (Exception ex)
    {
    }
    finally
    {
        testLString = null;
    }

宣言が実行時エラーをスローする可能性があるというあなたの懸念に同意しません。
宣言するだけです。

于 2012-09-08T13:00:31.293 に答える
0

try...catch必要な数の構造をネストできます。コードに独自のクリーンアップの責任を負わせるための良い方法です。

また、正常に実行されたかどうかに関係なく、常にクリーンアップが必要なコードに対してtryも構造体を使用することを検討してください。finally

try {

  // do something here

  // declare some variable
  try {
    // allocate space for variable
    // do something with that variable
  } fincally {
    // deallocate space for variable
  }

  // do something more here

} catch(Exception ex) {
  // handle the exception here
}

できるだけ具体的な例外クラスを使用するようにしてください。同じ構造で異なる型を使用して、異なる例外をキャッチできます。

try {
  // do some i/o
} catch (IOException ex) {
  // here you know that it was actually the i/o that failed
} catch (Exception ex) {
  // here is for catching anything else that might have failed
}
于 2012-09-08T13:12:11.783 に答える
0

アンマネージ API とのすべての通信をラップし、メモリなどを管理する別の型を作成することをお勧めします。これはIDisposable、実装がすべてのアンマネージ リソースをクリーンアップするインターフェイスを実装します。Windows を使用している場合、これを実現する最もクリーンな方法は、このラッパーを C++/CLI に実装することです。

于 2012-09-08T13:15:45.400 に答える