-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathAsyncSet.cs
46 lines (42 loc) · 1.22 KB
/
AsyncSet.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
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace DvMod.RemoteDispatch
{
public class AsyncSet<T>
{
private readonly object queueLock = new object();
private readonly SemaphoreSlim semaphore = new SemaphoreSlim(0);
private readonly Queue<T> queue = new Queue<T>();
public void Add(T item)
{
lock (queueLock)
{
if (!queue.Contains(item))
{
queue.Enqueue(item);
semaphore.Release();
}
}
}
public IEnumerable<T> TakeAll()
{
lock (queueLock)
{
var result = new List<T>();
while (semaphore.Wait(0))
result.Add(queue.Dequeue());
return result;
}
}
public async Task<(bool, T)> TryTakeAsync(TimeSpan timeSpan)
{
var success = await semaphore.WaitAsync(timeSpan).ConfigureAwait(true);
T value = default;
if (success)
lock (queueLock) value = queue.Dequeue();
return (success, value!);
}
}
}