Skip to content

Use ThrowIfCancellationRequested instead of simply returning #5343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Youssef1313
Copy link
Member

@Youssef1313 Youssef1313 commented Mar 30, 2025

@nohwnd What do you think?

cc @Evangelink @MarcoRossignoli

Fixes #5063

@Youssef1313 Youssef1313 marked this pull request as ready for review April 1, 2025 08:17
@Youssef1313 Youssef1313 requested a review from nohwnd as a code owner April 1, 2025 08:17
@Youssef1313
Copy link
Member Author

Ping @nohwnd for review

@nohwnd
Copy link
Member

nohwnd commented Apr 28, 2025

What is the benefit that this change brings? Is it to make sure that we are respecting the cancellation and don't get stuck in subsequent code that handles the return?

Do you have some link to best practices that say why we should prefer one over the other? 🙂

@Youssef1313
Copy link
Member Author

What is the benefit that this change brings? Is it to make sure that we are respecting the cancellation and don't get stuck in subsequent code that handles the return?

For our current code, it's mostly identical. But using ThrowIfCancellationRequested is the standard practice, and depending on the code present, there may be behavior difference between returning and throwing. Usually, callers of such cancellable methods will assume the method did complete successfully if it just returned normally. In situations that involve some caching (not something we do anywhere yet), it means that the caller may cache wrong info because it didn't differentiate between the method successfully completing its work and returning vs being cancelled.

@MarcoRossignoli
Copy link
Contributor

MarcoRossignoli commented Apr 28, 2025

my 2c

  • if the code returns to the platform control I prefer a return for perf reason...anyway we're exiting and we cannot avoid any race conditions on that cancellation(throw or boolean)...but cancel means whatever will be the result it's partial and should be discarded
  • if I'm a user of an extension I prefer return immediately for the same reason...if I didn't change any state nothing will change...if I change a local state I can throw or not...anyway before to use "that state" I should verify if it's valid or not

In general the platform handle the cancelled outcome/return value...so user can use or not the token correctly and bug aside we will be always correct(cooperative means that user could not cooperate).

@Youssef1313
Copy link
Member Author

I personally don't see a perf concern here. However, for our specific case (at least for the implementation that exists today, there is not much difference between returning vs throwing. So putting on hold for now.

@Youssef1313 Youssef1313 closed this May 2, 2025
@Youssef1313 Youssef1313 reopened this May 2, 2025
@Youssef1313 Youssef1313 marked this pull request as draft May 2, 2025 08:25
@Youssef1313
Copy link
Member Author

Youssef1313 commented May 2, 2025

At least for ConsumeAsync, while we are already just doing a return;, we will then get to here:

while (await _channel.Reader.WaitToReadAsync(_cancellationToken))

then .NET will do this:

https://github.com/dotnet/runtime/blob/f6b93319242155a72801a7bb4bc92faac2ada1a3/src/libraries/System.Threading.Channels/src/System/Threading/Channels/SingleConsumerUnboundedChannel.cs#L72-L75

So, when awaiting the canceled task, we will get a TaskCanceledException (derives from OperationCanceledException) and we will get to the catch anyways.

For the rest of usages, I suspect that currently we may be doing more work due to not observing cancellation correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Revise our usage of return; after IsCancellationRequested check
3 participants