Visual Studio 2008 のメニュー デバッグ/例外ダイアログのように、デバッグ時に例外で中断できるようにしたいのですが、デバッグしたいビットに到達する前にプログラムに多くの有効な例外があることを除きます。
毎回ダイアログを使用して手動で有効化および無効化する代わりに、 #pragma またはその他の方法で自動的に有効化および無効化して、特定のコードでのみ発生するようにすることはできますか?
Visual Studio 2008 のメニュー デバッグ/例外ダイアログのように、デバッグ時に例外で中断できるようにしたいのですが、デバッグしたいビットに到達する前にプログラムに多くの有効な例外があることを除きます。
毎回ダイアログを使用して手動で有効化および無効化する代わりに、 #pragma またはその他の方法で自動的に有効化および無効化して、特定のコードでのみ発生するようにすることはできますか?
これに近いことを行う唯一の方法は、メソッドに DebuggerNonUserCodeAttribute を配置することです。
これにより、マークされたメソッドの例外が例外で中断することはありません。
ここでそれについての良い説明...
これは、デバッガーに「私のコードとは関係ありません。私のコードではありません!」と伝えるためにメソッドに対して設定する属性です。だまされやすいデバッガーはあなたを信じ、そのメソッドを壊すことはありません。属性を使用すると、コードをステップ実行しているときでも、デバッガーはメソッドを完全にスキップします。例外が発生し、メソッド内でキャッチされても、デバッガーに割り込むことはありません。これは、フレームワーク アセンブリへの呼び出しであるかのように処理され、例外が処理されない場合は、メソッドを呼び出したコードで、コール スタックの 1 レベル上に報告されます。
コード例:
public class Foo
{
[DebuggerNonUserCode]
public void MethodThatThrowsException()
{
...
{
}
条件付きブレークポイントはどうですか?私が正しく理解していれば、特定の変数または式の値がtrueの場合にのみブレークポイントを起動できます。
trycatchブロックを#ifDEBUGでラップします
public void Foo()
{
#if DEBUG
try
#endif
{
//Code goes here
}
#if DEBUG
catch (Exception e)
{
//Execption code here
}
#endif
}
中括弧を#ifの外側に保持するのが好きです。そうすれば、デバッグの内側または外側でコードが同じスコープに保持されます。
それでも実行処理が必要であるが、より詳細な情報が必要な場合は、これを行うことができます
try
{
//code
}
catch (FileNotFoundException e)
{
//Normal Code here
#if DEBUG
//More Detail here
#endif
}
#if DEBUG
catch (Exception e)
{
//handel other exceptions here
}
#endif
これはあなたには少し遅すぎますが、これが私が人々に例外を保守的に使用するように教えようとする最大の理由です。壊滅的な事態が発生し、合理的に続行する能力がなくなった場合にのみ、例外を使用してください。
プログラムをデバッグするとき、アプリケーションをデバッグするために First Chance Exceptions (Debug -> Exceptions) をオンにすることがよくあります。多くの例外が発生している場合、何かが「間違っている」場所を見つけるのは非常に困難です。
また、悪名高い「キャッチ スロー」のようないくつかのアンチ パターンにつながり、実際の問題がわかりにくくなります。詳細については、この件に関して私が作成したブログ投稿を参照してください。
問題に関しては、特定の種類の例外に対してのみ初回デバッグを有効にすることができます。他の例外が同じタイプでない限り、これはうまく機能するはずです。
ブレークポイントの代わりにアサートを使用することもできます。たとえば、その関数を2回呼び出したときに、ループの5回目の反復でブレークポイントを設定するだけの場合は、次のように実行できます。
bool breakLoop = false;
...
Work(); // Will not break on 5th iteration.
breakLoop = true;
Work(); // Will break on 5th iteration.
...
public void Work() {
for(int i=0 ; i < 10 ; i++) {
Debug.Assert (!(breakLoop && i == 5));
...
}
}
したがって、Workへの最初の呼び出しでは、breakLoopがfalseである間、ループはアサートせずに実行され、2回目のループは中断されます。