There has been ongoing concern about the question of awaiting a task that could possibly be null, as when using null-coalescing operators. Consider the following:

var response = await turnContext?.SendActivityAsync("I am a bot");

That will throw a run-time exception when turnContext is null, as seen in questions like this: https://stackoverflow.com/questions/33592547/c-sharp-error-with-null-conditional-operator-and-await/33592569

Furthermore, if you use a ConfiguredTaskAwaitable<T> then the code won't even compile because it will be converted to a nullable struct that has no GetAwaiter:

var response = await turnContext?.SendActivityAsync("I am a bot").ConfigureAwait(false);

This can be made to compile by wrapping the null chain in parentheses so that ConfigureAwait remains a value type, but this will still cause null reference exceptions:

var response = await (turnContext?.SendActivityAsync("I am a bot")).ConfigureAwait(false);

To solve this issue, I've created an extension method to automatically check for nulls:

public static ConfiguredTaskAwaitable<T> CoalesceAwait<T>(
    this Task<T> task,
    bool continueOnCapturedContext = false)
=> (task ?? Task.FromResult<T>(default)).ConfigureAwait(continueOnCapturedContext);

This can be used in place of ConfigureAwait, and as a bonus I've made sure to have continueOnCapturedContext be false by default:

var response = await (turnContext?.SendActivityAsync("I am a bot")).CoalesceAwait();

The only problem is that you still need to wrap the null chain in parentheses which can be sort of awkward. I look forward to seeing if this is useful to anyone or if anyone has any other feedback.

  • \$\begingroup\$ If you want to give an explanation for your downvotes, a website exists for that purpose: idownvotedbecau.se \$\endgroup\$ Commented Feb 20, 2020 at 20:54
  • 3
    \$\begingroup\$ 1) I didn't downvote. 2) I didn't know that site supported Code Review. 3) Your question is attracting votes to close for missing review context. 4) While I'm far from fluent in C# .NET, I could understand why people would want more context here. There's a good base, you ran into a problem and found a fix which you want reviewed, but it still looks like a snippet. Hypothetical even, something we don't handle very well. Perhaps providing an actual usage example in a piece of code you actually use would help. \$\endgroup\$
    – Mast
    Commented Feb 20, 2020 at 21:24
  • \$\begingroup\$ @Mast - That's good information, thanks. I thought I had provided enough context by explaining that the problem is universal to async/await, and explaining the details of my project would be lengthy and irrelevant in a post that's already a good length. In any case, I've updated my code samples so they don't look like pseudocode. Also, can you explain what you mean when you say "I didn't know that site supported Code Review"? \$\endgroup\$ Commented Feb 20, 2020 at 22:09
  • 1
    \$\begingroup\$ The good stuff is frequently downvoted on here, Kyle. Thanks for this useful bit. \$\endgroup\$
    – xofz
    Commented Feb 20, 2020 at 22:12


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.