Frage zum Erstellen von FortschrittsbalkenHallo alle. Ich habe ein Fenster mit einem Fortschrittsbalken und einer Schaltfläche „Abbrechen“ erstellt. Die Absicht besteht darin, dem Benutzer zu ermöglichen, die Programmausführung zu stoppen. Ich erhalte jedoch eine Fehlermeldung, wenn ich auf „Abbrechen“ drücke, und weiß nicht, wie ich sie beheben kann. Eine vereinfachte Version meines Skripts finden Sie unten.
Names Default to Here(1);
//Define progress window
pwin = NewWindow("Progress",
SB_L = SpacerBox(Size(0, 15), Color("Green")),
ButtonBox("Cancel",
pwin << Close Window;
Stop();
)
);
//Sample Loop
For(i=1, i<=10, i++,
SB_L << Size(i*10, 15); //update the progress bar
Wait(1); //rest of loop
);Wenn ich bei laufender Schleife auf „Abbrechen“ drücke, erhalte ich die folgende Fehlermeldung:
deleted object reference: SB_L << Size(i * 10, 15) in access or evaluation of 'Glue' , pwin = New Window("Progress",
SB_L = Spacer Box(Size(0, 15), Color("Green")),
Button Box("Cancel",
pwin << Close Window;
Stop();
)
); /*###*/For(i = 1, i <= 10, i++,
SB_L << Size(i * 10, 15);
Wait(1);
) /*###*/;Wenn die Schaltfläche „Abbrechen“ gedrückt wird, erwarte ich, dass sich das Fortschrittsfenster schließt und die Ausführung dann stoppt. Aber es scheint mindestens eine Iteration lang weiterzumachen und schlägt an der Zeile SB_L << Size() in der For-Schleife fehl. Es schlägt fehl, weil das Fortschrittsfenster geschlossen wurde und SB_L gelöscht wurde, aber ich bin verwirrt, warum diese Zeile ausgeführt wird, wenn der Befehl Stop() ausgegeben wurde?
Liege ich richtig, dass die Programmausführung auch nach meinem Stop()-Befehl fortgesetzt wird? Wie kann ich die Ausführung des Befehls SB_L << Size() verhindern, nachdem die Schaltfläche „Abbrechen“ gedrückt wurde?
Einzelheiten:
JMP Pro 15.2.1
Mac OS Big Sur v11.6
Danke.
Erweiterte statistische ModellierungAutomatisierung und SkripterstellungDatenmischung und -bereinigungMassenanpassungQualitäts- und VerfahrenstechnikBetreff: Frage zum Erstellen von FortschrittsbalkenLeider können Sie hier nicht tun, was Sie wollen, ohne etwas zu tun, was im Grunde ein Hack für schlechte Praktiken ist.JMP-Skripte sind Single-Threaded und ein Fortschrittsbalken mit einer Schaltfläche zum Abbrechen macht meist nur in einem Multithread-System Sinn, in dem Sie die GUI/Ereignisschleife im Hauptthread und alle Skripte und Funktionsaufrufe in Arbeitsthreads haben.
Selbst in diesen Fällen benötigen Sie jedoch eine Art Wächter, um Stornierungen usw. ordnungsgemäß zu handhaben.Es wäre sicherlich möglich, eine Schaltfläche zum Abbrechen von Threads zu haben, aber im Allgemeinen benötigen Sie einen sicheren Stopppfad – eine Art Abbruchzweig.
Sie können dies in JSL tun, es erfordert jedoch beides Warten( ... ) Aussagen bzw <<FENSTER aktualisieren=""> Aussagen, die beide möglicherweise schwerwiegende Folgen haben.Insbesondere kann es vorkommen, dass während der Ereignisschleife unbeabsichtigt Code ausgeführt wird, der Variablennamen in Ihrem Skript verfälschen kann. Dies kann beispielsweise passieren, wenn ein Grafikskript in einem Diagramm vorhanden ist und ausgeführt wird (JMP führt Grafikskripte äußerst aggressiv aus) und diese Skripte auf dem System eines Benutzers von anderen Add-Ins vorhanden sein können, auf die Sie keinen Einfluss haben.Es ist auf jeden Fall am besten, die Ausführung nie wieder an die Ereignisschleife zu übergeben, bis Ihr Skript fertig ist (und natürlich das Skript so kurz wie möglich zu halten, um zu vermeiden, dass JMP eingefroren erscheint).Kurz und knapp: Geben Sie die Ausführung nicht an die Ereignisschleife zurück.</FENSTER>
Ich persönlich finde es etwas kurzsichtig vom JMP-Team, zum jetzigen Zeitpunkt (es ist fast 2022!) kein Multithread-Ausführungsparadigma in JSL zu haben, aber es ist, wie es ist.
Beachten Sie Folgendes: Sie können externe Programme ausführen und über STDOUT über IPC mit ihnen kommunizieren.Sie können beispielsweise Python verwenden, um eine Art Langzeitarbeit zu erledigen, und STDOUT verwenden, um zu wissen, wann sie fertig ist (und sogar ein JMP-Skript auf einer Art STDOUT-Sentinel starten).
Betreff: Frage zum Erstellen von FortschrittsbalkenJa. Das Schaltflächenskript wird in einem eigenen „Kontext“ ausgeführt. Es hat keine Ahnung, dass es ein anderes Skript gibt, das eine Warteanweisung ausführt. Sie können über Globals kommunizieren. Und um die seltsamen Möglichkeiten zu beenden, bedeutet die Verwendung einer Wartezeit in einem Schaltflächenskript auch, dass Sie auf das Schließen-X in dem Fenster klicken können, in dem das Skript ausgeführt wird. Wenn die Wartezeit beendet ist, versucht jmp, das Skript sicher zu stoppen. Normalerweise wird die nächste Anweisung nach dem Warten nicht ausgeführt, wenn das Fenster mit dem Schaltflächenskript während des Wartens geschlossen ist.
Bearbeiten: Außerdem ist eine Wartezeit erforderlich, um den Klick auf die Schaltfläche „Abbrechen“ zu verarbeiten.
Betreff: Frage zum Erstellen von FortschrittsbalkenHallo Craige! Danke. Nur zur Klarstellung: Das von mir hinzugefügte „Wait(1)“ diente nur dazu, die Ausführung eines längeren Befehlssatzes für diese Demo nachzuahmen und mir genügend Zeit zu geben, auf „Abbrechen“ zu klicken, damit ich das Problem reproduzieren konnte. Es war jedoch nicht beabsichtigt, dass das Warten ein notwendiger Teil des Skripts ist.
Wenn ich versuchen könnte, zusammenzufassen, was Sie meiner Meinung nach sagen:
Die Schaltfläche „Abbrechen“ ruft Skript B auf, das von Skript A unabhängig ist (das Hauptskript, das die For-Schleife enthält). Der Stop-Befehl im Skript B kann die Ausführung von Skript B stoppen, kann/wird sich jedoch nicht auf Skript A auswirken.
Habe ich das richtig, mehr/weniger?
Betreff: Frage zum Erstellen von Fortschrittsbalkenwait( n ) ist ein notwendiges Übel in JMP, das nach Möglichkeit vermieden werden sollte. Während eines Wartevorgangs wird das Skript, das den Wartevorgang aufruft, angehalten, während das Betriebssystem Dinge tun kann, beispielsweise einen Klick erkennt oder ein geöffnetes Fenster sichtbar macht. Es können seltsame Dinge passieren, weil Sie mit dem Klick ein anderes Skript (Ihr Beispiel) starten können, das die Umgebung des ersten Skripts berührt. In Ihrem Beispiel stoppt stop() das zweite Skript. Es kann auch ein globales Flag gesetzt werden. Wenn Ihr Projekt groß genug ist, um sich um die Nachverfolgung globaler Variablen zu kümmern, können Sie auch Namensräume verwenden.
Was ist also das Seltsame, das passieren kann? Meistens werden Fenster geschlossen oder Anzeigeboxen gelöscht. Stellen Sie sich insbesondere eine Klickfunktion vor, die über ein Skript verfügt, das wait(1) verwendet, und Sie klicken eine halbe Sekunde später erneut auf die Schaltfläche. Eine zweite Kopie des Skripts läuft innerhalb der ersten. Der ursprüngliche wait(1) wird erst zurückgegeben, wenn das zweite Skript abgeschlossen ist. Wenn das zweite Skript das Fenster schließt, in dem sich die Schaltfläche befindet, welche Umgebung befindet sich dann um das ursprüngliche Skript herum? (nicht dasselbe wie vor dem Warten!) Erstellen Sie keine Skripte, die ohne triftigen Grund warten müssen; Meistens ist displaybox<<
Betreff: Frage zum Erstellen von FortschrittsbalkenMir ist gerade noch etwas Interessantes aufgefallen. Wenn ich den Befehl „pwin << Close Window()“ im Skript für die Schaltfläche „Abbrechen“ auskommentiere, stoppt die Schaltfläche „Abbrechen“ die Ausführung nicht mehr. Es scheint, dass der Befehl Stop() die For-Schleife nicht stoppen kann, wenn er über eine Schaltfläche ausgeführt wird. Die Schaltfläche „Abbrechen“ konnte die Ausführung bisher nur stoppen, weil beim Entfernen des Fensters ein Fehler aufgetreten ist.
Betreff: Frage zum Erstellen von FortschrittsbalkenDanke Ryan (und Craige). Dies war eine Option, die ich auf jeden Fall in Betracht ziehe, aber sie erfordert das Senden eines Flags an eine if-Klausel im Hauptskriptkörper. Mein Wunsch ist es, die Programmausführung einfach mit dem Befehl „Stop()“ in der Schaltfläche „Abbrechen“ zu stoppen. Vielleicht kann ich meine Frage umformulieren: Warum scheint mein Stop()-Befehl die Ausführung nicht zu stoppen?
Betreff: Frage zum Erstellen von FortschrittsbalkenHallo @nikles . Vielleicht möchten Sie sich diesen aktuellen Beitrag von ansehen @Craige_Hales , Fortschrittsbalken mit Schaltfläche „Abbrechen“. .