SemaphoreExtensions.cs 1.2 KB

1234567891011121314151617181920212223242526272829303132
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. namespace GodotTools.IdeMessaging.Utils
  6. {
  7. public static class SemaphoreExtensions
  8. {
  9. public static ConfiguredTaskAwaitable<IDisposable> UseAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken = default(CancellationToken))
  10. {
  11. var wrapper = new SemaphoreSlimWaitReleaseWrapper(semaphoreSlim, out Task waitAsyncTask, cancellationToken);
  12. return waitAsyncTask.ContinueWith<IDisposable>(t => wrapper, cancellationToken).ConfigureAwait(false);
  13. }
  14. private struct SemaphoreSlimWaitReleaseWrapper : IDisposable
  15. {
  16. private readonly SemaphoreSlim semaphoreSlim;
  17. public SemaphoreSlimWaitReleaseWrapper(SemaphoreSlim semaphoreSlim, out Task waitAsyncTask, CancellationToken cancellationToken = default(CancellationToken))
  18. {
  19. this.semaphoreSlim = semaphoreSlim;
  20. waitAsyncTask = this.semaphoreSlim.WaitAsync(cancellationToken);
  21. }
  22. public void Dispose()
  23. {
  24. semaphoreSlim.Release();
  25. }
  26. }
  27. }
  28. }