'Move to New LINQPad Instance' does not respect QueryCancelToken
UserQuery.QueryCancelToken
(a.k.a. this.QueryCancelToken
) can be extremely useful at times. I'm using it to register cleanup handlers (flushing lazy writers etc. pp.) and to perform timed waits that are cancelled when the script is cancelled instead of making the script hang around until it is done sleeping. In fact, I've migrated several important scripts from LINQPad 5 (and hence Framework) to LINQPad 7 (with NET6) only because of this feature.
Unfortunately, the cleanup handler does not fire when right-clicking on the register tab for a running script and invoking 'Move to New LINQPad Instance' (which simply kills the old process cold). This opens the door for stuff like lost log entries etc. pp. when the user forgets to explicitly cancel the script before invoking this menu item.
Is there some other mechanism that can be exploited to e.g. flush lazy writers in connection with 'Move to New LINQPad Instance'?
Comments
P.S.: a similar argument could be applied to other LINQPad functions that implicitly kill/cancel currently running scripts, like the [Restart] button that is shown after LINQPad has updated itself. Or simply closing LINQPad, for that matter.
The LINQPad versions are 7.8.7 and 8.0.18.
With regard 'Move to new instance', I can easily make this initiate a soft cancellation if the query is running. With the other scenarios, the situation is more complex. When restarting, for instance, I'm not sure that LINQPad should refuse to close or restart because a query won't soft-cancel.
However, given that LINQPad will delay process destruction up to 750ms to ensure that active SQL queries are cancelled, it seems reasonable to honor cleanup initiated by soft cancellation that can complete within a similar amount of time. I'll get a fix into 8.1.3.
To ensure that cleanup code fires immediately, use the following pattern:
Joe, thank you for the positive feedback!
I've tried to analyse why I found it suprising that the cleanup hook does not fire for 'Move to New LINQPad Instance', whereas its not firing when closing LINQPad hardly even registered.
I guess the most salient aspect is this: when using the 'Move to New LINQPad Instance' action on running scripts, one quickly learns that this also stops the script. Hence the action gets translated mentally as 'cancel script and move to new instance'. In that sense it becomes another cancellation option alongside Shift-F5 or the cancel button, with the expection of similar behaviour.
Also, the action is directed specifically at a certain script. By contrast, the action of closing LINQPad is not directed at any one script in particular; the intent is to have LINQPad as a whole to go away, preferrably quickly. ;-)