2

オブジェクトの自動更新を管理するクラスに次のコードがあり、手動で更新することもできます。スレッドセーフにしたい。

Public Function ForceRefresh() As Foo
  DoRefresh()
  ResetTimer()
  Return Me.CurrentFoo
End Function

Private Sub DoRefresh()
  Me._currentFoo = Me._retriever.GetTheFoo()
End Sub

私はSynclockこれらの方法の両方に誘惑されます:

  • ForceRefresh:したがって、複数のコンシューマスレッドが同時に更新を強制し、タイマーをリセットしようとすることはありません。
  • DoRefreshGetTheFoo():ですから、すでに取得しようとしている最中の場合は、そうしようとはしません。System.Threading.Timerいずれかのスレッドでコールバックする可能性のあるものを使用ThreadPoolしているため、フラグを使用するだけでは適切でない場合があります(ただし、それでも必要ですか?)

... このような:

Private _syncRoot As New Object

Public Function ForceRefresh() As Foo
  Synclock _syncRoot
    'Snip ...
  End Synclock
End Function

Private Sub DoRefresh()
  Synclock _syncRoot
    'Snip ...
  End Synclock
End Sub

しかし、それから私は電話をするときに2回Synclockオンにしようとすることになります...今、再入可能であれば、これらをネストすることは問題にはなりません。MSDNのドキュメントページは、これが事実であることを示唆しているようですが、明示的には述べていません。_syncRootForceRefreshSynclock

注:これを自分で試してみるつもりですが、StackOverflowでこれについて何も表示されなかったため、回答しておくと便利な質問だと思いました。

4

1 に答える 1

4

SyncLock ステートメントは内部で Monitor.Enter() を使用します。MSDN ライブラリには次のように書かれています。

ブロックすることなく、同じスレッドが Enter を複数回呼び出すことは合法です

つまり再入可能です。ところでチェックするのは簡単。

于 2012-09-21T17:18:05.463 に答える