4

マルチスレッドコードの奇妙な動作をデバッグしようとしていますが、オブジェクトのIDを確実に追跡する方法が必要です。C ++では、オブジェクトアドレスを取得して文字列に変換するだけで、2つのアドレスが同じオブジェクトであるかどうかがわかります。

参照は、 C#のC++オブジェクトアドレスと完全に同等であるように見えます。

参照を文字列アドレス表現に変換できますか?

4

3 に答える 3

3

参照をポインターに変換してから数値に変換できますが、ガベージコレクターはいつでも参照を変更できるため、C#でオブジェクトを追跡するための信頼できる方法ではありません。参照から値をコピーすると、それがまだ参照を表していることを知ることはできません。

ただし、参照を安全に比較できます。参照がまだ参照である限り、ガベージコレクターはそれが最新であることを確認します。ガベージコレクターがオブジェクトを移動すると、そのオブジェクトへのすべての参照が更新されます。

したがって、参照を保持している限り、オブジェクトのIDとして参照を安全に使用できます。2つの参照を比較して、それらが同じオブジェクトを指しているかどうかを確認できます。

参照の値を別の形式に変換すると、その時点での参照のフラッシュコピーが得られます。その値を確認することは依然として有用かもしれませんが、100%信頼できるわけではありません。つまり、2つの参照の表現が異なるからといって、コピーの間に参照が変更されている可能性があるため、同じオブジェクトを指すことができないというわけではありません。最初のものと2番目のもの。

IntPtrそうは言っても、オブジェクトへのポインタを取得して、それを:に変換する方法は次のとおりです。

string str = "asdfasdf";
IntPtr p;

unsafe {
  // tell GC not to move the object, so that we can use a pointer to it
  fixed (void* ptr = str) {
    // here the object stays in place
    // make an IntPtr from the pointer, so we can keep it outside the fixed block
    p = new IntPtr(ptr);
  }
  // now the object can move again
}

Console.WriteLine(p);
于 2012-11-06T09:18:17.783 に答える
0

ある意味では、次のことができます。

GCHandle.Alloc(obj, GCHandleType.Pinned).AddrOfPinnedObject().ToString();

マルチスレッド アプリをデバッグする方法としてこれを使用しないでください。ダミアンが指摘したとおりにします。

于 2012-11-06T09:24:12.987 に答える