Skip to content

Commit

Permalink
remove discussion of Task-returning non-async methods (#23001)
Browse files Browse the repository at this point in the history
Fixes #16187

The usage of synchronous Task-returning methods is not generally recommended.  See https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#prefer-asyncawait-over-directly-returning-task

The examples were valid, but can cause hard-to-diagnose issues.

As we add more advanced async scenarios, this scenario belongs there, with more details about when it is and isn't appropriate. (`using` in the non-async method is the primary mistake to run into).
  • Loading branch information
BillWagner authored Mar 3, 2021
1 parent b2da32f commit f209668
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,6 @@ If you put iterator logic into a local function, argument validation exceptions

:::code language="csharp" source="snippets/local-functions/IteratorWithLocal.cs" :::

You can use local functions in a similar way with asynchronous operations. Exceptions thrown in an async method surface when the corresponding task is awaited. Local functions allow your code to fail fast and allow your exception to be both thrown and observed synchronously.

The following example uses an asynchronous method named `GetMultipleAsync` to pause for a specified number of seconds and return a value that is a random multiple of that number of seconds. The maximum delay is 5 seconds; an <xref:System.ArgumentOutOfRangeException> results if the value is greater than 5. As the following example shows, the exception that is thrown when a value of 6 is passed to the `GetMultipleAsync` method is observed only when the task is awaited.

:::code language="csharp" source="snippets/local-functions/AsyncWithoutLocal.cs" :::

Like with the method iterator, you can refactor the preceding example and put the code of asynchronous operation in a local function. As the output from the following example shows, the <xref:System.ArgumentOutOfRangeException> is thrown as soon as the `GetMultiple` method is called.

:::code language="csharp" source="snippets/local-functions/AsyncWithLocal.cs" :::

## Local functions vs. lambda expressions

At first glance, local functions and [lambda expressions](../../language-reference/operators/lambda-expressions.md) are very similar. In many cases, the choice between using lambda expressions and local functions is a matter of style and personal preference. However, there are real differences in where you can use one or the other that you should be aware of.
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static int LambdaFactorial(int n)
//</FactorialWithLambda>

//<AsyncWithLambda>
public Task<string> PerformLongRunningWorkLambda(string address, int index, string name)
public async Task<string> PerformLongRunningWorkLambda(string address, int index, string name)
{
if (string.IsNullOrWhiteSpace(address))
throw new ArgumentException(message: "An address is required", paramName: nameof(address));
Expand All @@ -87,12 +87,12 @@ public Task<string> PerformLongRunningWorkLambda(string address, int index, stri
return $"The results are {interimResult} and {secondResult}. Enjoy.";
};

return longRunningWorkImplementation();
return await longRunningWorkImplementation();
}
//</AsyncWithLambda>

//<AsyncWithLocal>
public Task<string> PerformLongRunningWork(string address, int index, string name)
public async Task<string> PerformLongRunningWork(string address, int index, string name)
{
if (string.IsNullOrWhiteSpace(address))
throw new ArgumentException(message: "An address is required", paramName: nameof(address));
Expand All @@ -101,7 +101,7 @@ public Task<string> PerformLongRunningWork(string address, int index, string nam
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException(message: "You must supply a name", paramName: nameof(name));

return longRunningWorkImplementation();
return await longRunningWorkImplementation();

async Task<string> longRunningWorkImplementation()
{
Expand Down

0 comments on commit f209668

Please sign in to comment.