publicstaticasyncTask<bool> taskName(){ Task pressBackButtonTask =Utils.WaitForPRessBackButton();Task finishedTask =awaitTask.WhenAny(pressBackButtonTask,..);await finishedTask; // Propagate exception if the task finished because of exceptionreturn finishedTask ==pressBackButtonTask.Result;}
Manual Cancellation
Every async function should take a cancellation token. This is needed to cancel a function for example when a gameobject is destroyed.
publicstaticasyncTask<bool> taskName(CancellationToken ct){ Task pressBackButtonTask =Utils.WaitForPRessBackButton(ct); // hereTask finishedTask =awaitTask.WhenAny(pressBackButtonTask,..);await finishedTask; // Propagate exception if the task finished because of exceptionreturn finishedTask ==pressBackButtonTask.Result;}
Clean up remaining tasks
publicstaticasyncTask<bool> taskName(CancellationToken ct){ var linkedCts =CancellationTokenSource.CreateLinkedTokenSource(ct);var linkedCt =linkedCts.Token;Task pressBackButtonTask =Utils.WaitForPRessBackButton(linkedCt); // NEW linkedCtTask finishedTask =awaitTask.WhenAny(pressBackButtonTask,..);await finishedTask; // Propagate exception if the task finished because of exceptionlinkedCts.Cancel(); //NEWreturn finishedTask ==pressBackButtonTask.Result;}
Dispose linked CancellationTokenSource
Dispose of the token source via "using block". Otherwise there could be a memory leak when the task is cancelled externally.
using (var linkedCts =CancellationTokenSource.CreateLinkedTokenSource(ct)){var linkedCt =linkedCts.Token; // do the workawait finishedTask;linkedCts.Cancel()return finishedTask ==pressBackButtonTask.Result;}
alternatively a try-finally block can be used:
var linkedCts =CancellationTokenSource.CreateLinkedTokenSource(ct);try {var linkedCt =linkedCts.Token; // do the workawait finishedTask;linkedCts.Cancel()return finishedTask ==pressBackButtonTask.Result;}finally{linkedCts.Cancel() // do some other ending work, e.g. play closing animation of popup}