This commit is contained in:
Kukks
2024-04-25 11:51:43 +02:00
parent f7cf0899ec
commit 6e95ddb8b1
8 changed files with 296 additions and 53 deletions

View File

@@ -0,0 +1,57 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;
namespace BTCPayServer.Plugins.Subscriptions;
public static class AsyncExtensions
{
/// <summary>
/// Allows a cancellation token to be awaited.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static CancellationTokenAwaiter GetAwaiter(this CancellationToken ct)
{
// return our special awaiter
return new CancellationTokenAwaiter
{
CancellationToken = ct
};
}
/// <summary>
/// The awaiter for cancellation tokens.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public struct CancellationTokenAwaiter : INotifyCompletion, ICriticalNotifyCompletion
{
public CancellationTokenAwaiter(CancellationToken cancellationToken)
{
CancellationToken = cancellationToken;
}
internal CancellationToken CancellationToken;
public object GetResult()
{
// this is called by compiler generated methods when the
// task has completed. Instead of returning a result, we
// just throw an exception.
if (IsCompleted) throw new OperationCanceledException();
else throw new InvalidOperationException("The cancellation token has not yet been cancelled.");
}
// called by compiler generated/.net internals to check
// if the task has completed.
public bool IsCompleted => CancellationToken.IsCancellationRequested;
// The compiler will generate stuff that hooks in
// here. We hook those methods directly into the
// cancellation token.
public void OnCompleted(Action continuation) =>
CancellationToken.Register(continuation);
public void UnsafeOnCompleted(Action continuation) =>
CancellationToken.Register(continuation);
}
}