-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Rationale
In order to facilitate the language feature at dotnet/csharplang#43 (async streams), which has been approved by the LDM and mostly implemented for C# 8.0, we should add the attribute DefaultCancellationAttribute to the framework. This attribute allows authors of async-enumerable methods to mark the parameter which should receive the cancellation token value from IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken). With this attribute, cancellation tokens can be passed in either way.
You'd use the attribute in conjunction with a defaulted parameter:
public async IAsyncEnumerable<T> Foo(int arg1, string arg2, [DefaultCancellation] CancellationToken cancellationToken = default)
{
...
await ...
...
yield return ...
...
}You can call it directly with a CancellationToken and enumerate the result with await foreach, in which case the attribute is meaningless, e.g.
CancellationToken token = ...;
await foreach (T item in Foo(42, "answer to everything", token)) { ... }but if you instead pass a token to the enumerable's GetAsyncEnumerator method, e.g.
CancellationToken token = ...;
IAsyncEnumerable<T> e = Foo(42, "answer to everything");
... = e.GetAsyncEnumerator(token);then the token fed into GetAsyncEnumerator will be auto-magically passed from GetAsyncEnumerator into the body of Foo as the cancellationToken argument. This is valuable because it lets you pass around an enumerable and then the consumer of that enumerable that's already been created can supply the CancellationToken to be used by the body of the iterator.
Proposal
namespace System.Runtime.CompilerServices
{
[System.AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class DefaultCancellationAttribute : Attribute
{
public DefaultCancellationAttribute();
}
}See also dotnet/roslyn#35121 (PR adding support for this attribute in the compiler)
FYI @stephentoub @terrajobst @jaredpar