How to abort evaluation of a sequence of inputs?

前端 未结 3 980
北海茫月
北海茫月 2020-12-10 19:57

By default pressing Alt+. or calling Abort[] within the evaluation causes abort of the currently evaluating input. But when working in the

相关标签:
3条回答
  • 2020-12-10 20:35

    Sasha's suggestion to just use four cells is valid, because that's basically what the FrontEnd does anyway, submitting several distinct evaluations to the Kernel. If you insist in using one cell, wrap it in parens (CompoundExpression), which causes those four lines to be treated as one evaluation (note the need for ; too):

    (
       f := CheckAbort[Pause[.1], Abort[]];
       While[True, f];
       While[True, f];
       While[True, f]
    )
    

    Then, one abort issued will abort the evaluation as a whole.

    0 讨论(0)
  • 2020-12-10 20:39

    Alexey, please try this version of your code and tell me if/when it fails:

    AbortAllPendingInputs :=
      AbortProtect[
        $new$PreRead = True;
        $TimeOfAbort = SessionTime[];
        last$PreRead = $PreRead;
        $PreRead = 
          If[
             TrueQ[SessionTime[] - $TimeOfAbort < 1], 
             "",
             $new$PreRead = False; $PreRead = last$PreRead; $PreRead[#]
            ] &;
      ] /; ! TrueQ[$new$PreRead]
    
    0 讨论(0)
  • 2020-12-10 20:55

    I have found a way to do what I want. The only problem is that at this moment I do not know how to check whether the FrontEnd has some pending inputs. I am forced just to wait 1 second. In the most cases it is sufficient time for sending all pending inputs to the kernel but probably not always.

    In[1]:= $new$PreRead = False;
    AbortAllPendingInputs := 
      AbortProtect[If[! $new$PreRead, $new$PreRead = True;
        $TimeOfAbort = SessionTime[];
        last$PreRead = ToString[Definition[$PreRead], InputForm];
        ClearAll[$PreRead];
        $PreRead := If[TrueQ[SessionTime[] - $TimeOfAbort < 1], "",
           $new$PreRead = False;
           ClearAll[$PreRead];
           If[last$PreRead === "Null", #, 
            ToExpression[last$PreRead]; $PreRead@#]
           ] &;]];
    
    In[3]:= f := CheckAbort[Pause[10], AbortAllPendingInputs; Abort[]]
    
    In[4]:= While[True, f]
    While[True, f]
    While[True, f]
    
    Out[4]= $Aborted
    

    But I am still looking for more elegant solution. I think that if the FrontEnd creates an input queue for MathKernel it probably can also cancel this queue.

    0 讨论(0)
提交回复
热议问题