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.
ListBox with scroll events
Simple extension of ListBox provides you vertical scroll event.
public class ListBoxScroll : ListBox { private const int WM_VSCROLL = 0x0115; private const int WM_HSCROLL = 0x0114; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_MOUSEHWHEEL = 0x020E; private const int SB_THUMBTRACK = 5; private const int SB_ENDSCROLL = 8; public delegate void ListBoxScrollDelegate(object a_sender, bool a_tracking); public event ListBoxScrollDelegate VerticalScroll; protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == WM_MOUSEWHEEL) { if (VerticalScroll != null) VerticalScroll(this, false); } if (m.Msg == WM_MOUSEHWHEEL) { if (VerticalScroll != null) VerticalScroll(this, false); } if (m.Msg == WM_VSCROLL) { int nfy = m.WParam.ToInt32() & 0xFFFF; if (VerticalScroll != null && (nfy == SB_THUMBTRACK || nfy == SB_ENDSCROLL)) { VerticalScroll(this, nfy == SB_THUMBTRACK); } } } }
Subskrybuj:
Posty (Atom)