Created
August 3, 2022 08:42
-
-
Save neuecc/895b1ae705479214ff74cae89e48c38e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Client : IDisposable | |
{ | |
readonly TimeSpan timeout; | |
readonly ObjectPool<CancellationTokenSource> timeoutTokenSourcePool; | |
readonly CancellationTokenSource clientLifetimeTokenSource; | |
public TimeSpan Timeout { get; } | |
public Client(TimeSpan timeout) | |
{ | |
this.Timeout = timeout; | |
this.timeoutTokenSourcePool = ObjectPool.Create<CancellationTokenSource>(); | |
this.clientLifetimeTokenSource = new CancellationTokenSource(); | |
} | |
public async Task SendAsync(CancellationToken cancellationToken = default) | |
{ | |
var timeoutTokenSource = timeoutTokenSourcePool.Get(); | |
CancellationTokenRegistration externalCancellation = default; | |
if (cancellationToken.CanBeCanceled) | |
{ | |
// call Timeout's cancel from argument CancellationToken | |
externalCancellation = cancellationToken.UnsafeRegister(static state => | |
{ | |
((CancellationTokenSource)state!).Cancel(); | |
}, timeoutTokenSource); | |
} | |
// same as Client's lifetime | |
var clientLifetimeCancellation = clientLifetimeTokenSource.Token.UnsafeRegister(static state => | |
{ | |
((CancellationTokenSource)state!).Cancel(); | |
}, timeoutTokenSource); | |
timeoutTokenSource.CancelAfter(Timeout); | |
try | |
{ | |
await SendCoreAsync(timeoutTokenSource.Token); | |
} | |
finally | |
{ | |
// Unregisters | |
externalCancellation.Dispose(); | |
clientLifetimeCancellation.Dispose(); | |
if (timeoutTokenSource.TryReset()) | |
{ | |
timeoutTokenSourcePool.Return(timeoutTokenSource); | |
} | |
} | |
} | |
async Task SendCoreAsync(CancellationToken cancellationToken) | |
{ | |
// snip... | |
} | |
public void Dispose() | |
{ | |
clientLifetimeTokenSource.Cancel(); | |
clientLifetimeTokenSource.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment