C
C#7mo ago
Hugh

✅ Creating new cancellation token from multiple other tokens

I've got function that is being passed in a cancellation token, and I want to cancel an inner function call if either this cancellation token is triggered, or another internal one is triggered (due to a timeout). My method looks something like this:
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = new();
timeoutCancellationTokenSource.CancelAfter(timeout);

// Create someCombinedCancellationToken which will cancel if either cancellationToken is cancelled
// or timeoutCancellationTokenSource is triggered

await DoSomethingElseAsync(someCombinedCancellationToken);
}
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = new();
timeoutCancellationTokenSource.CancelAfter(timeout);

// Create someCombinedCancellationToken which will cancel if either cancellationToken is cancelled
// or timeoutCancellationTokenSource is triggered

await DoSomethingElseAsync(someCombinedCancellationToken);
}
If there's no way of doing this, then I am thinking that I could do it something like this:
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = new();
timeoutCancellationTokenSource.CancelAfter(timeout);

Task result = DoSomethingElseAsync(timeoutCancellationTokenSource);
while(!result.IsCompleted)
{
if(cancellationToken.IsCancellationRequested)
{
timeoutCancellationTokenSource.Cancel();
}

await Task.Delay(100);
}
}
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = new();
timeoutCancellationTokenSource.CancelAfter(timeout);

Task result = DoSomethingElseAsync(timeoutCancellationTokenSource);
while(!result.IsCompleted)
{
if(cancellationToken.IsCancellationRequested)
{
timeoutCancellationTokenSource.Cancel();
}

await Task.Delay(100);
}
}
But it would be nice to know if there's a way of doing this with a combination cancellation token
1 Reply
Hugh
Hugh7mo ago
Straight after posting this, I did some better googling and found a solution. For reference, this would be done with:
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutCancellationTokenSource.CancelAfter(timeout);
await DoSomethingElseAsync(someCombinedCancellationToken);
}
public async Task DoSomethingAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
CancellationTokenSource timeoutCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
timeoutCancellationTokenSource.CancelAfter(timeout);
await DoSomethingElseAsync(someCombinedCancellationToken);
}