0

Is it possible to abort a synchronous method that executes for a long time?

I have the method Test that calls the LongRunningMethod method that consumes a lot of memory and CPU, in case it lasts longer than 30 seconds, I want to abort it. However, after an exception is thrown, the CPU and memory are still increasing, although the task is completed.

Code:

static async Task<string> Test (string input)
{
    var tokenSource = new CancellationTokenSource();
    var task = LongRunningMethod(input, tokenSource.Token)
        .WaitAsync(TimeSpan.FromSeconds(30));
    try
    {
        var result = await task;
        return result;
    }
    catch (Exception ex)
    {  
      // if the timeout is thrown, the LongRunningMethod still executes in background
      // and increase memory and CPU
    }
}

static Task<string> LongRunningMethod(string input, CancellationToken token)
{
    var task= Task.Run(() =>
    {
        SynchronousMethodThatConsumesMemoryAndCpu(input);
        return "end";
    },
    token);

    return task;
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
chessGeek
  • 11
  • 3
  • 1
    There is no answer to this question without knowing what is happening inside SynchronousMethodThatConsumesMemoryAndCpu. – Ralf Jan 17 '23 at 11:49
  • What .NET platform are you targeting? .NET Core and later or .NET Framework? For .NET Core see this: [.NET Core equivalent to Thread.Abort](https://stackoverflow.com/questions/53465551/net-core-equivalent-to-thread-abort) – Theodor Zoulias Jan 17 '23 at 11:53
  • I do not have access to that method, it does some conversion, however, I don't want to optimize it or write it differently, I am asking if it is possible to abort the execution of that method if I cannot pass CancellationToken. I am targeting .NET 6.0 – chessGeek Jan 17 '23 at 11:57
  • 3
    There are numerous question regarding this. But the only real alternatives are to change your `SynchronousMethodThatConsumesMemoryAndCpu` to check the cancellation token (or something equivalent), or to move the method to a separate process. – JonasH Jan 17 '23 at 12:52
  • 1
    See [Whats wrong with Thread.Abort](https://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort/1560567#1560567) for details. – JonasH Jan 17 '23 at 12:53
  • Deleting a question when people are trying to answer is very rude. Instead of guessing or insisting on things nobody else can reproduce, create a new web api project and try `curl -X 'GET' 'https://localhost:7011/WeatherForecast'`. You get `test`. Then add `-H 'accept: application/json'`. You get `"test"`. You aren't using the POSTMAN settings you think you are – Panagiotis Kanavos Mar 10 '23 at 14:45
  • If you hadn't deleted the question I could have posted how to force JSON when no content type is specified – Panagiotis Kanavos Mar 10 '23 at 14:46
  • Rude is saying that I am lying or telling something that I am not doing when actually I am – chessGeek Mar 11 '23 at 15:18
  • I already told you that I am using same request, only difference is the route. If you cannot accept that, please dont try to answer – chessGeek Mar 11 '23 at 15:19

1 Answers1

1

I don't want to optimize it or write it differently, I am asking if it is possible to abort the execution of that method if I cannot pass CancellationToken.

No, there isn't. There is no official helper method or other mechanism for cancelling/aborting a method which doesn't provide a mechanism to cancel/abort (e.g. accepting a token).

In addition, in a comment from March 2022 to Proposal for non-cooperative abortion of code execution #66480 the Microsoft's .NET performance guru Stephen Toub who has written many times about tasks and threads says:

We've deleted a whole bunch of code in .NET Core that was there to help try to improve reliability in the face of thread aborts (...)

New code has also been written assuming no thread aborts. (...)

This means that tricks with Thread.Interrupt are now even more dangerous.

It looks that you you would have to:

  1. Run the method in a separate process; or
  2. Let the method run to completion and just ignore its results if the 30 seconds have passed.
tymtam
  • 31,798
  • 8
  • 86
  • 126