-
-
Notifications
You must be signed in to change notification settings - Fork 939
Where to use SuppressCancellationThrow #590
-
If I start a chain of async calls, where do I need to put SuppressCancellationThrow if I don't want to try/catch at my top level when a cancellation happens? Does SuppressCancellationThrow trap throws under the covers and propagate a return value?
async UniTask DoThing(CancellationToken token){ var isCancelled = await DoAnotherThing(token).SuppressCancellationThrow(); } async UniTask DoAnotherThing(CancellationToken token){ await DoTheLastThing(token); } async UniTask DoTheLastThing(CancellationToken token) { await UniTask.Delay(1000, cancellationToken: token); // If cancelled in here is the SuppressCancellationThrow at the top enough? }
Also is there a way to just never throw and just check the token yourself as I would prefer not to have to use SuppressCancellationThrow.
async UniTask<bool> DoIt(){ await UniTask.Delay(1000, cancellationToken: token); return token.IsCancellationRequested);
Cheers.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 3 replies
-
Unfortunately, cancellations cannot be propagated without throwing. SuppressCancellationThrow
only suppresses it for the current async function, and you have to throw again to keep propagating it higher up. The only way currently to get around it is to manually return a value containing the cancellation state. UniTask<bool>
instead of UniTask
, or UniTask<(T result, bool isCancelled)>
instead of UniTask<T>
.
Upvote the csharplang issue if you would like it natively supported in the language.
Does SuppressCancellationThrow trap throws under the covers and propagate a return value?
Yes and no. Under the hood, each async function traps throws. When you await the returned UniTask
normally, it just throws it again. Using SuppressCancellationThrow
simply doesn't throw again.
Beta Was this translation helpful? Give feedback.
All reactions
-
Many thanks for the reply. I'll take a look over that proposal when I get a chance.
For my use case I'd be happy if the propagation wasn't done, just that throwing wasn't mandated on cancellation and I could test for cancellation and exit.
await SomeTaskThatCouldCancel(cancellationToken); // If cancelled, should not throw if(cancellationToken.IsCancellationRequested){ return 42; }
Effectively an implicit SuppressCancellationThrow. Of course functions lower down that aren't under my control could do anything and break this with their own cancellation tokens but for almost all of my use cases, the code is all ours, or leaves are UniTask.Delay() etc.
Beta Was this translation helpful? Give feedback.
All reactions
-
Well, you can't suppress cancellation throws without calling SuppressCancellationThrow
. The only way you could do that would be to write your own task-like type that wraps UniTask
and calls SuppressCancellationThrow
for its GetAwaiter
.
Of course, if you own all your async functions, you could just not throw when the token is cancelled. You may find that to be a maintainability nightmare in the future, though. 😉
Beta Was this translation helpful? Give feedback.
All reactions
-
Yeah I hear you re maintenance.
On that second point - we ALMOST own it all, except or things like UniTask.Delay :) But I get you and was missing something obvious. I could use SuppressCancellationThrow just on Delay and handle everything else up the chain ourselves.....if we wanted.
Beta Was this translation helpful? Give feedback.