1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- 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;
- }
- _semaphore.Release();
- return false;
- }
- }
- public class QueueSemaphoreToken : IDisposable
- {
- internal event EventHandler OnDisposed;
- public void Dispose()
- {
- OnDisposed?.Invoke(this, EventArgs.Empty);
- }
- }
|