public class OrderedList<K, V>
{
private SortedList<K, List<V>> m_list = new SortedList<K, List<V>>();
public void Add(K a_key, V a_value)
{
if (Values.Contains(a_value))
throw new Exception();
if (!Keys.Contains(a_key))
m_list.Add(a_key, new List<V>());
m_list[a_key].Add(a_value);
}
public IEnumerable<V> Values
{
get
{
foreach (var sublist in m_list.Values)
foreach (var v in sublist)
yield return v;
}
}
public IEnumerable<K> Keys
{
get
{
return m_list.Keys;
}
}
public void RemoveByValue(V a_value)
{
foreach (var sublist in m_list.Values)
{
if (sublist.Remove(a_value))
break;
}
}
public int Count
{
get
{
return Values.Count();
}
}
public V RemoveFirst()
{
V v = Values.First();
RemoveByValue(v);
return v;
}
}
public class QueuedSemaphore<P>
{
private Object m_lock = new Object();
private OrderedList<P, ManualResetEvent> m_queue =
new OrderedList<P, ManualResetEvent>();
private int m_working = 0;
private readonly int m_count;
public QueuedSemaphore(int a_count)
{
m_count = a_count;
}
public void WaitOne(CancellationToken a_token, P a_priority)
{
ManualResetEvent mre = null;
lock (m_lock)
{
if (m_working == m_count)
{
mre = new ManualResetEvent(false);
m_queue.Add(a_priority, mre);
}
else
m_working++;
}
if (mre != null)
{
while (!mre.WaitOne(100))
{
if (a_token.IsCancellationRequested)
{
lock (m_lock)
{
if (mre.WaitOne(0))
Release();
else if (m_queue.Values.Contains(mre))
m_queue.RemoveByValue(mre);
}
a_token.ThrowIfCancellationRequested();
}
}
}
}
public void WaitOne(P a_priority)
{
ManualResetEvent mre = null;
lock (m_lock)
{
if (m_working == m_count)
{
mre = new ManualResetEvent(false);
m_queue.Add(a_priority, mre);
}
else
m_working++;
}
if (mre != null)
mre.WaitOne();
}
public void Release()
{
lock (m_lock)
{
if (m_queue.Count != 0)
{
m_queue.RemoveFirst().Set();
}
if (m_queue.Count < m_working)
m_working = m_queue.Count;
}
}
}
2011-03-05
Semaphore with FIFO order and priorities.
Semaphore with FIFO order and priorities. Also support cancelation token.
Subskrybuj:
Komentarze do posta (Atom)
Brak komentarzy:
Prześlij komentarz