Silverlight 용 간단한 (업그레이드 또는 시간 초과 없음) ReaderWriterLock의 구현이 adopted인데, 설계 상으로는 좋거나 나쁘면 올바른 전문 지식을 가진 사람이 확인할 수 있는지 궁금합니다. 나에게 그것은 꽤 괜찮아 보인다. 광고되는 것처럼 작동하지만, 나는 멀티 스레딩 코드에 대한 경험이 제한적이다. 이 좋은 경우에 실버 라이트가 현재 잠금의 리더 라이터 타입 부족으로Silverlight ReaderWriterLock 구현 좋음/나쁨?
public sealed class ReaderWriterLock
{
private readonly object syncRoot = new object(); // Internal lock.
private int i = 0; // 0 or greater means readers can pass; -1 is active writer.
private int readWaiters = 0; // Readers waiting for writer to exit.
private int writeWaiters = 0; // Writers waiting for writer lock.
private ConditionVariable conditionVar; // Condition variable.
public ReaderWriterLock()
{
conditionVar = new ConditionVariable(syncRoot);
}
/// <summary>
/// Gets a value indicating if a reader lock is held.
/// </summary>
public bool IsReaderLockHeld
{
get
{
lock (syncRoot)
{
if (i > 0)
return true;
return false;
}
}
}
/// <summary>
/// Gets a value indicating if the writer lock is held.
/// </summary>
public bool IsWriterLockHeld
{
get
{
lock (syncRoot)
{
if (i < 0)
return true;
return false;
}
}
}
/// <summary>
/// Aquires the writer lock.
/// </summary>
public void AcquireWriterLock()
{
lock (syncRoot)
{
writeWaiters++;
while (i != 0)
conditionVar.Wait(); // Wait until existing writer frees the lock.
writeWaiters--;
i = -1; // Thread has writer lock.
}
}
/// <summary>
/// Aquires a reader lock.
/// </summary>
public void AcquireReaderLock()
{
lock (syncRoot)
{
readWaiters++;
// Defer to a writer (one time only) if one is waiting to prevent writer starvation.
if (writeWaiters > 0)
{
conditionVar.Pulse();
Monitor.Wait(syncRoot);
}
while (i < 0)
Monitor.Wait(syncRoot);
readWaiters--;
i++;
}
}
/// <summary>
/// Releases the writer lock.
/// </summary>
public void ReleaseWriterLock()
{
bool doPulse = false;
lock (syncRoot)
{
i = 0;
// Decide if we pulse a writer or readers.
if (readWaiters > 0)
{
Monitor.PulseAll(syncRoot); // If multiple readers waiting, pulse them all.
}
else
{
doPulse = true;
}
}
if (doPulse)
conditionVar.Pulse(); // Pulse one writer if one waiting.
}
/// <summary>
/// Releases a reader lock.
/// </summary>
public void ReleaseReaderLock()
{
bool doPulse = false;
lock (syncRoot)
{
i--;
if (i == 0)
doPulse = true;
}
if (doPulse)
conditionVar.Pulse(); // Pulse one writer if one waiting.
}
/// <summary>
/// Condition Variable (CV) class.
/// </summary>
public class ConditionVariable
{
private readonly object syncLock = new object(); // Internal lock.
private readonly object m; // The lock associated with this CV.
public ConditionVariable(object m)
{
lock (syncLock)
{
this.m = m;
}
}
public void Wait()
{
bool enter = false;
try
{
lock (syncLock)
{
Monitor.Exit(m);
enter = true;
Monitor.Wait(syncLock);
}
}
finally
{
if (enter)
Monitor.Enter(m);
}
}
public void Pulse()
{
lock (syncLock)
{
Monitor.Pulse(syncLock);
}
}
public void PulseAll()
{
lock (syncLock)
{
Monitor.PulseAll(syncLock);
}
}
}
}
, 너무 다른 사람에게 도움이 될 수 있습니다. 감사.
Vance Morrison의 구현에 대해 알려 주시고 저에게 알려 주셔서 감사합니다. 실제로 Silverlight에서 최소한의 변경만으로 구현 된 구현을 얻었으며 너무 빠르게 실행됩니다. 나는 나의 blog에 그것을 되 돌리는 약간의 수를 내놓을 것이다. 건배. –