I see microsoft enforces this pattern for async methods:
async Task<object> DoMyOperationAsync(int par1, string par2,..., CancellationToken token=default(CancellationToken))
{
...
CancellationToken.ThrowIfRequested();
...
}
Every single method should have that ugly CancellationToken token=default(CancellationToken)
parameter even though most of the time it's not even being used, but just passed through at best.
Why instead of this we cannot just use some sort of CancellationTokenContext, and use it in methods that actually need it?
public class CancellationTokenContext
{
static AsyncLocal<CancellationToken> asyncContext = new AsyncLocal<CancellationToken>();
public static CancellationToken Current {
get {
return asyncContext.Value;
}
set {
asyncContext.Value = value;
}
}
public static void ThrowIfRequested() {
Current.ThrowIfCancellationRequested();
}
}
public class MyClassWithAsyncMethod{
public async Task<object> DoMyOperationAsync(int par1, string par2,...)
{
...
CancellationTokenContext.ThrowIfRequested();
...
}
}
The main reason for not using AsyncLocal
is that it's much slower. In fact, it's a dictionary lookup, so it should be approximate 20x slower (~ 20ns vs 1ns).
One other factor is: explicit is usually better than implicit. Though I agree it's a very annoying part of async implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With