Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Where to use SuppressCancellationThrow #590

Unanswered
aaronatweta asked this question in Q&A
Discussion options

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.

You must be logged in to vote

Replies: 1 comment 3 replies

Comment options

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.

You must be logged in to vote
3 replies
Comment options

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.

Comment options

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. 😉

Comment options

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /