Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about proper CancellationToken usage within awaitable methods #110108

Closed
WizardBrony opened this issue Nov 23, 2024 · 5 comments
Closed
Labels
area-System.Threading.Tasks question Answer questions and provide assistance, not an issue with source code or documentation.

Comments

@WizardBrony
Copy link
Contributor

public Task Method1Async(CancellationToken token)
{
    if (token.IsCancellationRequested)
        return Task.FromCanceled(token);
    // ...
}

public Task Method2Async(CancellationToken token)
{
    token.ThrowIfCancellationRequested();
    // ...
}

Given the following common usage of awaitable methods:

var method2Task = Method2Async(token);
// ...
try
{
    await method2Task;
}
catch (OperationCanceledException)
{
    // ...
}

or since .NET 8.0:

var method2Task = Method2Async(token);
// ...
await method2Task.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);

do the .NET design guidelines consider Method2Async as having a bug? I haven't seen any official statements, so links to relevant documentation would be appreciated.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 23, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-threading-tasks
See info in area-owners.md if you want to be subscribed.

@stephentoub
Copy link
Member

do the .NET design guidelines consider Method2Async as having a bug?

Yes. All exceptions in Task-returning methods, other than argument validation, should emerge asynchronously via the returned Task rather than being propagated out synchronously.

@stephentoub stephentoub added question Answer questions and provide assistance, not an issue with source code or documentation. and removed untriaged New issue has not been triaged by the area owner labels Nov 23, 2024
@WizardBrony
Copy link
Contributor Author

Yes. All exceptions in Task-returning methods, other than argument validation, should emerge asynchronously via the returned Task rather than being propagated out synchronously.

Thank you very much for confirming.

@julealgon
Copy link

do the .NET design guidelines consider Method2Async as having a bug?

Yes. All exceptions in Task-returning methods, other than argument validation, should emerge asynchronously via the returned Task rather than being propagated out synchronously.

@stephentoub can you clarify? That is only the case because the method lacks the async modifier, correct?

If it had async and some await in the body, token.ThrowIfCancellationRequested(); would be considered appropriate as it would be returned as part of the observed Task in that case.

@stephentoub
Copy link
Member

do the .NET design guidelines consider Method2Async as having a bug?

Yes. All exceptions in Task-returning methods, other than argument validation, should emerge asynchronously via the returned Task rather than being propagated out synchronously.

@stephentoub can you clarify? That is only the case because the method lacks the async modifier, correct?

If it had async and some await in the body, token.ThrowIfCancellationRequested(); would be considered appropriate as it would be returned as part of the observed Task in that case.

My statement is about observable behavior. However it's implemented, that should be the observable behavior.

Using async/await is an implementation detail. And, yes, if you use async to implement a Task-returning method, all exceptions thrown from the body of the method will be stored into the returned Task rather than propagating out of the call synchronously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Threading.Tasks question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

3 participants