-
Notifications
You must be signed in to change notification settings - Fork 22
/
BlockingQueue.cs
62 lines (54 loc) · 1.19 KB
/
BlockingQueue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using IEnumerator = System.Collections.IEnumerator;
class BlockingQueue<T> : IEnumerable<T>, IDisposable where T : class
{
private readonly Queue<T> _queue = new Queue<T>();
private Semaphore _semaphore = new Semaphore(0, int.MaxValue);
public void Enqueue(T data)
{
if (data == null) throw new ArgumentNullException("data");
lock (_queue) _queue.Enqueue(data);
_semaphore.Release();
}
public T Dequeue()
{
_semaphore.WaitOne();
lock (_queue) return _queue.Dequeue();
}
public bool TryDequeue(int timeout, out T result)
{
if (!_semaphore.WaitOne(timeout))
{
result = null;
return false;
}
lock (_queue) result = _queue.Dequeue();
return true;
}
public int Count
{
get
{
return _queue.Count;
}
}
void IDisposable.Dispose()
{
if (_semaphore != null)
{
_semaphore.Close();
_semaphore = null;
}
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
while (true) yield return Dequeue();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
}