Let's have a code like this (fragment of App.xaml.xs):
public class MethodClass
{
public async Task Job()
{
Debug.WriteLine("Doing some sob");
await Task.Delay(1);
}
}
public MethodClass MyClass = null;
protected async override void OnLaunched(LaunchActivatedEventArgs e)
{
await MyClass?.Job(); // here goes NullreferenceException
MyClass?.Job(); // works fine - does nothing
Why Elvis operator doesn't work with async-await? Am I missing something?
Top-level code, up to and including the first await expression (if there is one), is run synchronously. In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronouslyasynchronouslyAsynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished. Once that task has finished, your program is presented with the result.https://developer.mozilla.org › Asynchronous › IntroducingIntroducing asynchronous JavaScript - Learn web development | MDN.
The possible suspension points in your code marked with await indicate that the current piece of code might pause execution while waiting for the asynchronous function or method to return.
The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.
The map doesn't resolve the promisespromisesIn other cases a future and a promise are created together and associated with each other: the future is the value, the promise is the function that sets the value – essentially the return value (future) of an asynchronous function (promise).https://en.wikipedia.org › wiki › Futures_and_promisesFutures and promises - Wikipedia on its own but left the stuff for the developer to resolve. So, that means you can't use async-await in the map.
The way await
is translated is that first, GetAwaiter()
is called on the awaited object (in your case, a Task
). It then does some other complicated things, but those are not relevant here:
await MyClass?.Job();
Compiles to:
var awaiter = MyClass?.Job().GetAwaiter();
// more code
Since Task.GetAwaiter()
is an instance method and you're calling it with a null
Task
, you get a NullReferenceException
.
As a curiosity, it is possible to await
a null
awaitable, as long as its GetAwaiter()
is an extension method that accepts null
:
public class NullAwaitable { }
public static class Extensions
{
public static TaskAwaiter GetAwaiter(this NullAwaitable _)
=> Task.CompletedTask.GetAwaiter();
}
public class MethodClass
{
public NullAwaitable Job() => new NullAwaitable();
}
MethodClass MyClass = null;
await MyClass?.Job(); // works fine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With