This file contains 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 | |
{ | |
// called from IDisposable.Dispose | |
readonly CancellationTokenSource clientLifetimeTokenSource; | |
public TimeSpan Timeout { get; } | |
public Client(TimeSpan timeout) | |
{ | |
this.Timeout = timeout; | |
this.clientLifetimeTokenSource = new CancellationTokenSource(); | |
} | |
public async Task SendAsync(CancellationToken cancellationToken = default) | |
{ | |
using var cts = CancellationTokenSource.CreateLinkedTokenSource(clientLifetimeTokenSource.Token, cancellationToken); | |
cts.CancelAfter(Timeout); | |
try | |
{ | |
await SendCoreAsync(cts.Token); | |
} | |
catch (OperationCanceledException ex) when (ex.CancellationToken == cts.Token) | |
{ | |
if (cancellationToken.IsCancellationRequested) | |
{ | |
// Error reason is argument CancellationToken | |
throw new OperationCanceledException(ex.Message, ex, cancellationToken); | |
} | |
else if (clientLifetimeTokenSource.IsCancellationRequested) | |
{ | |
// Error reason is client's dispose | |
throw new OperationCanceledException("Client is disposed.", ex, clientLifetimeTokenSource.Token); | |
} | |
else | |
{ | |
// Error reason is timeout | |
throw new TimeoutException($"The request was canceled due to the configured Timeout of {Timeout.TotalSeconds} seconds elapsing.", ex); | |
} | |
} | |
} | |
async Task SendCoreAsync(CancellationToken cancellationToken) | |
{ | |
// nanika... | |
} | |
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