8

次のコードを検討してください。

var weakRef = new WeakReference(new StringBuilder("Mehran"));
if (weakRef.IsAlive)
{
    // Garbage Collection might happen.
    Console.WriteLine((weakRef.Target as StringBuilder).ToString());
}

GC.Collectチェック後weakRef.IsAlive、 を使用する前にを実行することは可能ですweakRef.Target

私はこれで間違っていますか?可能であれば、安全な方法はありますか?

たとえば、次のような APIweakRef.GetTargetIfIsAlive()が適切です。

4

4 に答える 4

12

その API は既に存在します。オブジェクトがすでにガベージ コレクションされている場合はweakRef.Target戻ります。null

StringBuilder sb = weakRef.Target as StringBuilder;
if (sb != null)
{
    Console.WriteLine(sb.ToString());
}
于 2013-02-13T15:17:15.423 に答える
10

プロパティは、ターゲットが生きている場合にターゲットを使用したいコードの利益のために存在するのIsAliveではなく、ターゲットが死んでいるかどうかを調べたいが、ターゲットにアクセスすることに関心がないコードの利益のために存在します。場合。コードがTargetnull に対してテストする場合Target、強力なルート参照 (null に対してテストしているコード) が一時的に存在することになり、そのようなルート参照を生成する行為によって、オブジェクトがガベージ コレクションされるのを防ぐことができる可能性があります。そうでなければそうなるでしょう。Targetコードがまだ無効化されているかどうかを確認する以外にコードに関心がない場合、コードが参照を取得する理由はありません。代わりに単純にテストIsAliveして、 が返された場合に適切なアクションを実行できますfalse

于 2013-02-27T22:55:08.217 に答える
1

ターゲットのローカル コピーを取得し、null をチェックします。

WeakReference.Targetターゲットが収集された場合は返されますが、チェックとターゲットの取得のnull間に収集されていることが懸念されます。.IsAlive

var weakRef = new WeakReference(new StringBuilder("Mehran"));

if (weakRef.IsAlive)
{
    var stringBuilder = weakRef.Target as StringBuilder;

    if (stringBuilder != null)
    {
        Console.WriteLine(stringBuilder.ToString());
    }
}

Console.WriteLine((weakRef.Target as StringBuilder).ToString());キャストが失敗すると、null 参照例外がスローされます。

于 2013-02-13T15:19:50.433 に答える