Skip to content

Improve "Async return types" docs #47289

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

xakep139
Copy link
Contributor

@xakep139 xakep139 commented Jul 11, 2025

Summary

This PR rephrases a misleading statement regarding an awaiter type - an AsyncMethodBuilderAttribute should be applied on a type that an async method returns, not on a type that GetAwaiter() method returns.

The same requirement is showcased in the spec - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#15141-general.

As an example:

async CustomTask SomeMethodAsync() { /* ... */ }

// The attribute should be applied here:
[AsyncMethodBuilder(typeof(CustomAsyncMethodBuilder))]
class CustomTask
{
    public CustomAwaiter GetAwaiter() { /* ... */ }
}

class CustomAwaiter : INotifyCompletion
{
    public void OnCompleted(Action continuation) { /* ... */ }
}

internal class CustomAsyncMethodBuilder
{
    // The builder must implement a bunch of methods like (only a few required are listed):
    public static CustomAsyncMethodBuilder Create() { /* ... */ }
    public void SetException(Exception exception) { /* ... */ }
    public void SetResult() { /* ... */ }
    public CustomTask Task { get; }
}

Rigth now the documentation states that an AsyncMethodBuilderAttribute should be applied on a CustomAwaiter type from the example above, which is misleading.


Internal previews

📄 File 🔗 Preview link
docs/csharp/asynchronous-programming/async-return-types.md Async return types (C#)

@xakep139 xakep139 requested review from BillWagner and a team as code owners July 11, 2025 08:38
@dotnetrepoman dotnetrepoman bot added this to the July 2025 milestone Jul 11, 2025
@dotnet-policy-service dotnet-policy-service bot added dotnet-csharp/svc async-task-programming/subsvc community-contribution Indicates PR is created by someone from the .NET community. labels Jul 11, 2025
Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @xakep139

Thanks for spotting this. However, the fix isn't correct either. I looked back at the spec and made a suggestion for different text.

@@ -71,7 +71,7 @@ The following example shows the behavior of an async event handler. In the examp

## Generalized async return types and ValueTask\<TResult\>

An async method can return any type that has an accessible `GetAwaiter` method that returns an instance of an *awaiter type*. In addition, the type returned from the `GetAwaiter` method must have the <xref:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute?displayProperty=nameWithType> attribute. You can learn more in the article on [Attributes read by the compiler](../language-reference/attributes/general.md#asyncmethodbuilder-attribute) or the C# spec for the [Task type builder pattern](~/_csharpstandard/standard/classes.md#15142-task-type-builder-pattern).
An async method can return any type that has an accessible `GetAwaiter` method that returns an instance of an *awaiter type*. In addition, that type with a `GetAwaiter` method must have the <xref:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute?displayProperty=nameWithType> attribute. You can learn more in the article on [Attributes read by the compiler](../language-reference/attributes/general.md#asyncmethodbuilder-attribute) or the C# spec for the [Task type builder pattern](~/_csharpstandard/standard/classes.md#15142-task-type-builder-pattern).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither the original article nor this PR is correct. Let's try this instead:

Suggested change
An async method can return any type that has an accessible `GetAwaiter` method that returns an instance of an *awaiter type*. In addition, that type with a `GetAwaiter` method must have the <xref:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute?displayProperty=nameWithType> attribute. You can learn more in the article on [Attributes read by the compiler](../language-reference/attributes/general.md#asyncmethodbuilder-attribute) or the C# spec for the [Task type builder pattern](~/_csharpstandard/standard/classes.md#15142-task-type-builder-pattern).
An async method can return any type that has an accessible `GetAwaiter` method that returns an instance of an *awaiter type*. In addition, the returned type must match the type of the parameter of `SetResult` and returned type of the `Task` property on the type specified by the <xref:System.Runtime.CompilerServices.AsyncMethodBuilderAttribute?displayProperty=nameWithType> attribute. You can learn more in the article on [Attributes read by the compiler](../language-reference/attributes/general.md#asyncmethodbuilder-attribute) or the C# spec for the [Task type builder pattern](~/_csharpstandard/standard/classes.md#15142-task-type-builder-pattern).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
async-task-programming/subsvc community-contribution Indicates PR is created by someone from the .NET community. dotnet-csharp/svc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants