I’m trying out Awaitable now.
Is there any problem on my script?
This script outputs elapsed time each second.
Of course, while I cancel this awaitable on Start(),
it will not print out log to console at all.
But, actually it does print elapsed time each time.
I don’t know why at all. Should I use CancellationToken?
I don’t understand them sufficiently. (Almost nothing!)
I could achieve the behavior what I want by utilizing CancellationTokenSource.Cancel(),
whereas I don’t know how limitation and constraint, performance are.
But, my problem have not been solved completely yet.
I should learn more to replace IEnumerator API in practical scenarios.
Thanks for your suggestions!
Thank you for reply.
Of cource, I know UniTask.
Yeah, it is the simplest and most robust solution ever.
I will continue to test Awaitable more time, then I will have decided to migrate to UniTask.
Generally you should be cancelling async stuff pretty rarely. 99% of my cancellation tokens are either MonoBehaviour.destroyCancellationToken or Application.exitCancellationToken to shut down async code when exiting play mode, or closing the application. Does mean you do need to pass them from the root async call all the way to the end point.
So I think rather than cancelling stuff, if you want async code to end early, you should just code it to return early; same as you would normally code things really.
Use async code to help write code more linearly, aka ‘functional programming’. It can help reduce the need for callbacks, and make your code more straightforward and readable.
Im with spiney on this, cancellation is like pulling the plug on your pc (Ok not quite that harsh but in that direction), I certainly wouldnt throw a cancel to leave, id have some boolean flags like other things
All it does is it causes an OperationCanceledException to get thrown by an async method that awaits the Awaitable. It does not actually stop the async state machine from continuing to run in the background.
public async void Start()
{
awaitable = DoSomethingAsync();
try
{
await awaitable;
}
catch(OperationCanceledException) // <- thrown if awaitable.Cancel is executed
{
Debug.Log("Awaitable was cancelled.");
return;
}
finally
{
awaitable = null // <- always clear references to Awaitables after they complete
}
Debug.Log("Awaitable completed successfully.");
}
You should also be careful to never call Awaitable.Cancel after the Awaitable has already completed. Otherwise you could accidentally end up raising an exception in some completely unrelated async method that is waiting for the completion of some completely unrelated method that returns an Awaitable, since Awaitable instances are pooled behind the scenes.
CancellationTokens should be used instead of Awaitable.Cancel in basically all situations that I can think of.
Thanks for all replies.
I feel lacking for my knowledge about awaitable and cancellation.
I have thought over my practical purpose again.(This sample code is abstraction of it.)
Then, I realize that I doesn’t have to use Awaitable strongly.
But I’m going to learn about awaitable and async programming more.
Thank you all!