Runtime: Non-cooperative cancellation/abort/interrupt for interactive execution environments

Created on 24 Aug 2020  路  6Comments  路  Source: dotnet/runtime

There are a range of execution environments for .NET code that have historically utilised non-cooperative cancellation. These environments have the following characteristics

  1. in-process compilation and execution

  2. execute arbitrary .NET code entered interactively by the user

  3. use arbitrary .NET libraries

  4. most user code runs solely on one specific known thread

  5. these are developer scenarios (not production scenarios) - in the sense that the developer is issuing the abort while coding/executing and it is not happening as a routine part of production execution

  6. reliability of the cancellation mechanism must be "good" but need not be "perfect" - occasional weirdness requiring process restart is tolerated by the developer.

Examples are

  • the F# REPL (dotnet fsi)

  • the C# REPL (dotnet csi)

  • .NET Interactive notebook kernels

and likely many others.

On .NET Framework these have previously relied on Thread.Abort() to support some cancellation scenarios (user enters code, preses run and suddenly decides that wasn't a good idea). However Thread.Abort() has been removed from .NET Core, see https://github.com/dotnet/runtime/issues/11369

At the moment it's impossible to have an "Interrupt" button in any .NET execution environment executing arbitrary user code, ever. For example, .NET Interactive Jupyter notebooks can't support the Jupyter "Interrupt" button to stop user code execution, or a future .NET teaching environment can't ever have an "Interrupt" button. And REPLs can't support Ctrl-C, one of the most basic functions of a REPL.

These scenarios matter for the long term future of .NET.

This continues the discussion about production scenarios here: https://github.com/dotnet/runtime/issues/11369#issuecomment-443433749

@jkotas said

We still have the "good enough" thread abort functionality available for debuggers via debugging APIs. If the other debugger-like environments cannot act as real debuggers, I would not be opposed to exploring ways how to make the thread abort available to them.

@dsyme said:

In theory it might be possible to rearchitect the F# REPL to use a supervised process but it would be a large amount of work. And that work would likely be needed again for .NET Interactive and C# REPL. It's very different to what we are doing today for F# Interactive etc....

Finally @dsyme suggested this:

If it were possible to put on the agenda a System.Runtime.Helpers.UnsafeThreadAbortOnlyForUseByInteractiveExecutionEnvironmentsActingAsTheirOwnSupervisor() that would be grand....

api-suggestion area-VM-coreclr

Most helpful comment

class ControlledExecutionForUseByInteractiveExecutionEnvironmentsActingAsTheirOwnSupervisor
{
    public ControlledExecution(Action action);
    // This can have more method and properties to control the execution
    void Run();
    void Abort();
}

All 6 comments

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

class ControlledExecutionForUseByInteractiveExecutionEnvironmentsActingAsTheirOwnSupervisor
{
    public ControlledExecution(Action action);
    // This can have more method and properties to control the execution
    void Run();
    void Abort();
}

@jkotas Ship it :)

Seriously it would be fantastic to have this addressed. No massive design needed really, just a replacement for thread abort is enough from my perspective.

Am I right in thinking this would be fairly simple to implement, ie the basic abort mechanisms are still in place?

I guess it's worth asking if there is other non-coop thread control functionality lying around (pause?) that could enable user gestures in a REPL without embracing being a full debugger. But equally abort is really enough to warrant this.

I think it would be medium (ie several weeks of work) sized feature.

OK cool. Please let me know who else we need to bring on board, if anyone, or if you feel it can be driven from your side

I almost daily actively use Thread.Abort in my iterative F# scripting. I have to host F# interactive in a bigger CAD process. see my talk please allow in process cancellation of threads so that I can move to NET 5 eventually too.

Was this page helpful?
0 / 5 - 0 ratings