System.ServiceModel.Channels.BufferManager のソース コードを見ていると、次のメソッドに気付きました。
void TuneQuotas()
{
if (areQuotasBeingTuned)
return;
bool lockHeld = false;
try
{
try { }
finally
{
lockHeld = Monitor.TryEnter(tuningLock);
}
// Don't bother if another thread already has the lock
if (!lockHeld || areQuotasBeingTuned)
return;
areQuotasBeingTuned = true;
}
finally
{
if (lockHeld)
{
Monitor.Exit(tuningLock);
}
}
//
// DO WORK... (code removed for brevity)
//
areQuotasBeingTuned = false;
}
明らかに、実行するスレッドは 1 つだけでTuneQuotas()
、別のスレッドによって既に実行されている場合、他のスレッドは待機しません。削除されたコードは保護されていないことに注意してください。
これを行うだけでなく、上記のこの方法の利点を理解しようとしています:
void TuneQuotas()
{
if(!Monitor.TryEnter(tuningLock)) return;
//
// DO WORK...
//
Monitor.Exit(tuningLock);
}
なぜ彼らがそのすべてに悩まされたのか、何か考えはありますか? 彼らがブロックを使用する方法は、スレッドの中止シナリオを防ぐことだと思いますが、このコードをすべて使用しても、その 1 つのスレッドがすべてを実行しない場合、永久にロックされるfinally
ため、まだ要点がわかりません。なんらかの理由で、set までの道のり。では、このパターンについて私が見逃しているクールなものはありますか?TuneQuotas()
areQuotasBeingTunes=false
EDIT: 補足として、フレームワーク4で実行されているこのコードを使用して確認した.NET 4.0にメソッドが存在するようです(ただし、メソッドの内容がWebで見つけたものから変更されていないことは確認できません) :
var buffMgr = BufferManager.CreateBufferManager(1, 1);
var pooledBuffMgrType = buffMgr.GetType()
.GetProperty("InternalBufferManager")
.GetValue(buffMgr, null)
.GetType();
Debug.WriteLine(pooledBuffMgrType.Module.FullyQualifiedName);
foreach (var methodInfo in pooledBuffMgrType
.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic))
{
Debug.WriteLine(methodInfo.Name);
}
出力:
C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Runtime.DurableInstancing\v4.0_4.0.0.0__3 1bf3856ad364e35\System.Runtime.DurableInstancing.dll
ChangeQuota
DecreaseQuota
FindMostExcessivePool
FindMostStarvedPool
FindPool
IncreaseQuota
TuneQuotas
Finalize
MemberwiseClone