12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace EVCB_OCPP.WSServer.Helper;
- public class QueueSemaphore
- {
- public QueueSemaphore(int maxLimit)
- {
- this._queue = new();
- this._semaphore = new(maxLimit);
- }
- private readonly ConcurrentQueue<SemaphoreSlim> _queue;
- private readonly SemaphoreSlim _semaphore;
- public async Task<QueueSemaphoreToken> GetToken()
- {
- //if (_semaphore.Wait(0))
- //{
- // return CreateToken();
- //}
- SemaphoreSlim _selfSemaphore = new(0);
- _queue.Enqueue(_selfSemaphore);
- TryDequeue();
- await _selfSemaphore.WaitAsync();
- return CreateToken();
- }
- private QueueSemaphoreToken CreateToken()
- {
- QueueSemaphoreToken token = new ();
- token.OnDisposed += Token_OnDisposed;
- return token;
- }
- private void Token_OnDisposed(object sender, EventArgs e)
- {
- var token = sender as QueueSemaphoreToken;
- token.OnDisposed -= Token_OnDisposed;
- _semaphore.Release();
- TryDequeue();
- }
- private bool TryDequeue()
- {
- if (!_semaphore.Wait(0))
- {
- return false;
- }
- if (_queue.TryDequeue(out var semaphore))
- {
- semaphore.Release();
- return true;
- }
- return false;
- }
- }
- public class QueueSemaphoreToken : IDisposable
- {
- internal event EventHandler OnDisposed;
- public void Dispose()
- {
- OnDisposed?.Invoke(this, EventArgs.Empty);
- }
- }
|