-
Notifications
You must be signed in to change notification settings - Fork 779
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
Async.AwaitTask does not cancel on workflow cancellation #2127
Comments
Looks like by design.
|
@majocha OK. In that case it seems to me that |
It's not hanging. If you wait for 24 days it will throw the exception :) |
So this seems by design. Can we close this? |
@dsyme Perhaps, the fact that replacing |
The point being |
@eiriktsarpalis I guess it's not possible. Tasks have no built-in cancellation, unlike async workflows. Task cancellation is cooperative only. |
@majocha as you said, an async workflow awaiting on a task can be cancelled using the built-in mehanism. |
I've updated the issue topic to better reflect the actual issue |
@eiriktsarpalis Isn't this by design? You have to grab the ambient cancellation token from the async context and pass it into the task creation - there's just no other way. Giving some warning when the ambient cancellation token could have been passed to some overload could in theory be feasible, though quirky to implement |
@dsyme To clarify, I'm not saying we should try to cancel the awaited task. You are right to say this is not achievable in general and I may add wrong. I am however suggesting we should make the task awaiter honor the ambient cancellation token and fire the cancellation continuation regardless of task outcome. Here is a proof of concept: http://fssnip.net/7Rw |
I'm not sure that this is right thing to do since |
As an alternative we can do the following:
Downside: |
@vladima parameterizing the behaviour is an interesting proposition. Pretty sure it can be achieved without introducing dependency on net45. I would argue that eager cancellation makes for a better default but you make a good point and preserving backward compatibility is always a winner. |
We hit this issue at work this week. The fact that Async.AwaitTask doesn't cancel the task it creates when the Async is cancelled was causing huge memory leaks in our system. I opened #7357 to fix this, which we've had to also rewrite in terms of Async.FromContinuations to use in our system for now. I don't think this behavior should be parameterized, it just shouldn't be possible to leak continuations. |
Discussion about this came up again at work this week. We discussed how there's actually separate cases where you need to transform a Task into an Async. Case 1) Your treating a Task as an external event to the workflow. This is the situation we had at work in 2019 where we had a Async.Choice that was listening to two Tasks to see which completed first, but we didn't want to cancel the other task when the first finished. We wrote our own version of AwaitTask that respected async cancellation for this purpose. Case 2) Your creating a Task as part of the async workflow (like calling into ReadAsync or something). In this case your trying to make the Task fit into the async workflow and the right way to do this is to pass the workflows cancellation token to the thing making the task, and then in AwaitTask wait for the task itself to get cancelled (in the same way how if your awaiting another async you expect it to respect the cancellation and return that up). A work college suggested that case 2 might be better done with the method signature Given so much probably already depends on the current semantics of AwaitTask it might be better to add an overload for Case 1 instead. |
This issue seems unfocused in that it's covering Ultimately, there's no obvious behavior change in the impl of FSharp.Core that could resolve the forces outlined. I suggest closing this one on the basis that the concerns it covers are better addressed via the combination of:
|
Not sure whether a bug or by design, but I have discovered a hanging behaviour that seems to be related to the cancellation of sibling computations in the event of an exception
Repro steps
Expected behavior
Should fail immediately with an exception
Actual behavior
Hangs indefinitely
Known workarounds
Have the awaited task cancel cooperatively by passing the cancellation token.
Related information
I've been able to reproduce this in builds of F# 4.1 in Desktop CLR and mono.
The text was updated successfully, but these errors were encountered: