私はこの問題をしばらく前から調査してきましたが、通常のブレークポイントの配置がプログラムの実行時の動作に劇的な影響を与えることは明らかです。
ここでは、条件付きブレークポイントについて話します。たとえば、ブレークポイント条件を設定するとvar == null
、このケースは発生しませんが、ブレークポイントを削除すると、var == null
頻繁に発生する状況になります。
それでいいの?
付録:
私のコードはマルチスレッドなので、エラーを再現するためにコードを投稿するのは難しいです。基本的に私は2つのスレッドを持っています。1つはキュー内のアイテムをキューに入れ、もう1つはキューからアイテムを永続的にデキューします。以下のコードスニップでは、最初のスレッドがnullアイテムをキューに入れることはありませんが、何らかの理由でキューに入る方法を見つけているという状況があります。これにより、 NullReferenceExceptionを防ぐためにifステートメントを挿入できます。一時的な回避策ですが、それ以降、私のプログラムは実行されました。次に、nullアイテムがキューからデキューされる頻度に関心があり、条件付きのifステートメントの行に条件付きブレークポイントを配置しました。inv == null
。現在の効果は、ブレークポイントがある場合はinvがnullに見えず、ブレークポイントがない場合はinvがnullになることが多いということです。
public void _dequeue () {
while (!Signals.TerminateSignal.WaitOne(0, false)) {
if (Signals.DequeueSignal.WaitOne()) {
lock (Queue) {
IInvocation inv;
Queue.TryDequeue(out inv);
// Conditional Breakpoint
if (inv != null)
inv.Invoke();
_poolHooks[PoolIndex].DecrementWaiting();
_poolHooks[PoolIndex].IncrementPending();
if (Queue.Count == 0) Signals.DequeueSignal.Reset();
}
}
}
}
再び私の問題は、キュー内のいくつかのアイテムがnullアイテムになり始めたときに始まりましたが、nullアイテムを追加することはありません。そのためでも、何かnullがある場合に例外をスローする行を配置しました。例外がスローされることはありませんが、キューにnullアイテムが残っているため、理由がわかりません。
public static void EnqueueInvocation (int poolIndex, IInvocation inv ) {
if (inv == null) throw new Exception("Red Alert");
lock (_deqThreads[poolIndex].Queue) {
_poolHooks[poolIndex].IncrementWaiting();
_deqThreads[poolIndex].Queue.Enqueue(inv);
_deqThreads[poolIndex].Signals.DequeueSignal.Set();
}
}