0

I have used CancellationToken in ActionFilter to cancel a task if user closes the tab after GET request (as this is heavy task i.e. takes time 20 sec and memory also).

if (!token.IsCancellationRequested)
{
   token.Register(() => { throw new OperationCanceledException(token); });
}

In Controller action I have GetAsync method which does the heavy calculation.

Now when GET request is hit from browser and after 5 sec I closed the browser tab, it throws the Exception and Continues the execution till completion. I want it to stop the processing further and release memory and CPU.

I have used the breakpoint after cancelling the task , it stills calculates the results(18,00,000 results) which is no use and also cancelling has no effect except the exception thrown.

I also can't pass the token to Controller and do some stuff there as due to Open/Close principle.

I tried Environment.Exit(0) but it closes the IIS Express and stop the server.

Please tell me a method to release memory and CPU usage as soon as cancellation exception thrown.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
RISHU GUPTA
  • 493
  • 6
  • 8
  • Are you using the Thread class, or tasks here ? – TheGeneral Oct 26 '21 at 05:50
  • 6
    Signaling a CancellationToken has limited effect just by itself. Your long-running task has to check it every now and then and cancel itself cooperatively. Unless you actually abort the thread (which is usually not a good idea). – John Wu Oct 26 '21 at 05:52
  • take a look at this : https://stackoverflow.com/questions/22273463/cancellation-token-and-thread-not-working – fmansour Oct 26 '21 at 05:55
  • @TheGeneral Actually My Controller method has type "async Task". – RISHU GUPTA Oct 26 '21 at 05:57
  • 2
    This question is difficult because there are a bunch of assumptions that need to be made to work out exactly what you are doing. You need to show the minimal structure of what you are doing. obviously if you have registered with the cancelation token and throw that seemingly would be enough to tear down the thread, however who knows what you have done. – TheGeneral Oct 26 '21 at 06:03
  • 1
    `token.Register(() => throw new ... )`, so when the token is cancelled, an exception is immediately thrown. That won't have any effect on the execution of your thread, you need to throw an exception from within your loop. Perhaps by calling `ThrowIfCancellationRequested` periodically. – Jeremy Lakeman Oct 26 '21 at 06:15
  • @JeremyLakeman I was wondering about that, my assumption was that the exception would have be thrown on the thread it was registered in. However that was just an assumption and seems very very very dubious and wrong when I typed it out aloud – TheGeneral Oct 26 '21 at 06:31
  • 1
    You have to modify the actual code that does the work to be aware of the cancellation token and act on cancellation. There's a reason why [`Thread.Abort`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.abort?view=net-5.0) is strongly recommended against - experience shows that *yanking the thread, memory, etc out from under code that's not ready for it* leads to bad behaviour and difficult to diagnose bugs. – Damien_The_Unbeliever Oct 26 '21 at 06:55
  • @TheGeneral if the thread is busy with processing, it it cannot also process events, since a thread can only do one thing at a time. So the solution, as others have mentioned, is to check the token in the loop. – JonasH Oct 26 '21 at 08:42
  • @TheGeneral From controller I have used Builder Design Pattern which has 4 methods run after another and calculates the result. Now I don't get the cancellationToken in Builder Pattern methods to check in loop. – RISHU GUPTA Oct 27 '21 at 06:35

0 Answers0