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

Not clear when the return task of an async function is set to a cancelled state #775

Closed
pkulikov opened this issue Apr 16, 2023 · 4 comments · Fixed by #1027
Closed

Not clear when the return task of an async function is set to a cancelled state #775

pkulikov opened this issue Apr 16, 2023 · 4 comments · Fixed by #1027
Assignees
Milestone

Comments

@pkulikov
Copy link
Contributor

pkulikov commented Apr 16, 2023

13.10.6 The throw statement section contains the following sentence:

If the current function is async and task-returning, the exception is recorded in the return task, which is put into a faulted or cancelled state as described in §15.15.2.

The linked 15.15.2 section contains only the following sentence relevant to the quoted sentence from 13.10.6:

If the function body terminates as the result of an uncaught exception (§13.10.6) the exception is recorded in the return task which is put into a faulted state.

When I read the sentence in 13.10.6, I expect that 15.15.2 explains the two things

  • when the task is put into a faulted state and
  • when the task is put into a cancelled state.

The current text of 15.15.2 doesn't explain that difference. Even more, it doesn't mention the cancelled state at all. So, one may think that the return task is always put into a faulted state, if an exception is thrown. That is not true, as the following example shows:

using System;
using System.Threading.Tasks;

public static class Program
{
    public static async Task Main(string[] args)
    {
        Task t = Async();
        try
        {
            await t;
        }
        catch
        {
            Console.WriteLine(t.IsFaulted);  // False
            Console.WriteLine(t.IsCanceled); // True
        }
    }

    public static async Task Async() => throw new OperationCanceledException();
}

So, 15.15.2 misses the description of when the return task is set to a cancelled state.


Associated WorkItem - 187389

@svick
Copy link
Contributor

svick commented Apr 16, 2023

Isn't this a BCL concern and so shouldn't be described in detail by the C# specification in the first place?

@KalleOlaviNiemitalo
Copy link
Contributor

Cancellation is also involved in IAsyncEnumerable<T> #606, in which EnumeratorCancellationAttribute needs compiler support and in my opinion should be standardised.

@SamB
Copy link

SamB commented Jun 30, 2023

At the very least, the first quoted passage shouldn't say "is put into a faulted or cancelled state as described in [section that doesn't actually describe that]", right?

If the actual logic is in the BCL, then sure, it's fine if the referenced section merely refers in turn to the relevent BCL method documentation (whatever that might be), but if the logic gets open-coded then it should probably actually be described in the spec.

@KalleOlaviNiemitalo
Copy link
Contributor

If an application defines and uses a task builder type whose builder.SetException(e) method does the same as builder.SetResult(default), i.e. does not record the exception, then does that violate the standard? How about if a C# implementation does that, in a task builder type that is not used for Task or Task<TResult>?

Perhaps 13.10.6 should say something like:

If the current function is async and task-returning, the exception is passed to the SetException method of the task builder as described in §15.15.2. [Note: In the task builder types associated with Task and Task<TResult>, SetException records the exception in the return task and puts it into a faulted or cancelled state.]

@jskeet jskeet added this to the Pre-C# 8.0 milestone Sep 21, 2023
@BillWagner BillWagner self-assigned this Nov 30, 2023
@BillWagner BillWagner moved this from 🔖 Ready to 🏗 In progress in dotnet/docs December 2023 sprint Dec 7, 2023
BillWagner added a commit to BillWagner/csharpstandard that referenced this issue Dec 7, 2023
Fixes dotnet#775

Add a bullet to the list specifying that an `OperationCanceledException` puts the returned task in the cancelled state.

This meant adding `OperationCanceledException` to the types in Annex C.

I chose this fix because all known task builders conform to this behavior. It seems reasonable to standardize it.
@BillWagner BillWagner moved this from 🏗 In progress to 👀 In review in dotnet/docs December 2023 sprint Dec 7, 2023
@BillWagner BillWagner moved this from 🔖 Ready to 👀 In review in dotnet/docs January 2024 sprint Jan 11, 2024
@BillWagner BillWagner moved this from 🔖 Ready to 👀 In review in dotnet/docs February 2024 sprint Jan 11, 2024
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in dotnet/docs February 2024 sprint Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: 👀 In review
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

6 participants