Используя рефлектор .NET, я обнаружил, что структура SpinLock имеет много случаев, когда она вызывает Thread.BeginCriticalRegion и не вызывает Thread.EndCriticalRegion .Например, в публичной функции SpinLock.Enter (ref bool lockTaken) (.NET 4.0):
// ...
Thread.BeginCriticalRegion();
if (Interlocked.CompareExchange(ref this.m_owner, managedThreadId, owner, ref lockTaken) == owner)
return; // <--- !!
Thread.EndCriticalRegion();
// ...
В другом случае SpinLock.Exit, кажется, вызывает Thread.EndCriticalRegion безвызвав Thread.BeginCriticalRegion .
public void Exit(bool useMemoryBarrier)
{
if (this.IsThreadOwnerTrackingEnabled && !this.IsHeldByCurrentThread)
throw ...
if (useMemoryBarrier)
{
if (this.IsThreadOwnerTrackingEnabled)
Interlocked.Exchange(ref this.m_owner, 0);
else
Interlocked.Decrement(ref this.m_owner);
}
else if (this.IsThreadOwnerTrackingEnabled)
this.m_owner = 0;
else
{
int owner = this.m_owner;
this.m_owner = owner - 1;
}
Thread.EndCriticalRegion(); // <--- ??
}
Итак, возникает вопрос: возникают ли какие-либо проблемы из-за несбалансированности вызовов Begin / EndCriticalRegion?