You can await anything in C# 5+ so long as the type has a function called .GetAwaiter()
that returns a special object or has a extension method that does the same.
Unity3d in its next major release is going to be supporting async/await. Currently in Unity3d you can yield return null;
inside a coroutine to represent "Wait for next frame".
I was wondering if it is possible to craft a extension method that would allow you to do await null;
to get the same behavior. There is no System.Null
like there is a System.Void
, so I could not think of what type to put in the extension method.
You are right that yield and await are closely related. Both are points in a workflow where the current method is paused, control is returned to the caller, and the method resumes at an unspecified point in the future at the point where the yield / await happened.
But they are very different in terms of their action on their operands. They are in fact duals of each other. A yield provides a new value when demanded by the code iterating the sequence. An await extracts a value when it is produced by the asynchronously executing task.
Null is a perfectly valid value, so it makes sense for a yield to proffer it up to its caller. But null is not a valid task, and so it makes no sense for await to attempt to extract the value from the task.
Currently in Unity3d you can yield return null; inside a coroutine to represent "Wait for next frame".
In an async-await asynchronous workflow the analog of yield return null;
is just return null;
. That means "end this portion of the asynchronous workflow by providing the null reference". Why are you not simply returning null if you intend to produce a task whose result is null?
Let me put it another way that might be more clear. Obviously this makes no sense:
foreach(var x in null)
Console.WriteLine(x);
This is identically nonsensical:
var x = await null;
Console.WriteLine(x);
These are the same thing logically. Foreach means "extract a value from the sequence as long as values are available", but null is not a sequence. Similarly, "await" means "extract a value from the task as soon as a value is available", but null is not a task.
That's the key: the asynchronous analog of await
is not yield return
, it's foreach
. That's the mechanism that extracts the T
from the IEnumerable<T>
or Task<T>
. The thing that puts the T
into the monadic type is yield return
for IEnumerable<T>
and return
for Task<T>
.
There's no way to define an extension method on a literal null, since a literal null
has no type:
.. we realized that the null type was bizarre. It is a type with only one value — or is it? Is the value of a null nullable int really the same as the value of a null string? And don’t values of nullable value type already have a type, namely, the nullable value type?
And:
Therefore we removed references to the useless “null type” in the C# 3.0 specification.
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