2

nullになる可能性のあるオブジェクトをSyncLockする簡単な方法はありますか?

そして、あなたがそれを求める前に、はい、null 変数に対して SyncLock を実行することは論理的ではないことを知っています。ただし、今のところ、SyncLock を呼び出す前にすべての場所で null チェックを実行する以外に選択肢がないため、コードが簡素化されます。

If myObjectA Is Nothing Then
  myObjectA = myObjectB
Else
  SyncLock myObjectA
    myObjectA = myObjectB
  End SyncLock
End If
4

3 に答える 3

4

はい、ヘルパー オブジェクトを使用します。

ロックとして使用されている場合は、とにかく myObjectA に割り当てないでください。

MSDNから:

オブジェクト値をロックします。lockobject の値を Nothing にすることはできません。SyncLock ステートメントで使用する前に、ロック オブジェクトを作成する必要があります。

SyncLock ブロックの実行中に lockobject の値を変更することはできません。このメカニズムでは、ロック オブジェクトが変更されないままにしておく必要があります。

于 2011-03-25T18:00:28.353 に答える
3

これらの状況を回避するのに役立つリファクタリングがおそらくいくつかあります。このコードは奇妙に思えます。nullの場合はオブジェクトをロック変数に割り当て、そうでない場合はロックするのはどういうわけか間違っているようです。さらに、ロックしてからロック変数を変更します。

ロックは値ではなく参照に行われることを忘れないでください!基本的には、ロック内にないコードのすべてのブロックから、指定された参照へのブロックアクセスを行います。

于 2011-03-25T18:04:07.060 に答える
3

いいえ、null 参照をロックの識別子として使用することはできません。

null の可能性がある場合、参照を識別子として使用することさえできないため、現在のコードはスレッドセーフではありません。ロックを識別するには、別の方法を使用する必要があります。2 つの異なるスレッドが互いに除外することなく null 参照を置き換えることができます。これにより、一方の参照が他方によって上書きされます。

If myObjectA Is Nothing Then
  ' Here another thread can change the reference, believing that it's safe
  myObjectA = myObjectB
Else
  SyncLock myObjectA
    myObjectA = myObjectB
  End SyncLock
End If
于 2011-03-25T18:15:28.490 に答える