Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
eben hast Du mir einen Vorschlag gemacht, SubVIs mittels FGV (alternativ auch Melder/Queues) zu beenden.
Das hatte ich früher auch so gemacht. Aber mein Programm besteht aus mehreren Modulen und die einzelnen Module beinhalten oft auch eine separate Ereignisstruktur. Ich hatte deshalb das Problem, dass ich diese Programmblöcke dann nicht beenden konnte (also das Beenden-Ereignis in der Eventstruktur auslösen). Deshalb bin ich vor einiger Zeit mit Eurer Hilfe auf die Benutzerevents gestoßen. Ich löse also im Hauptprogramm beim Beenden ein Beenden-Ereignis auf, dass von allen subVIs mit Eventstruktur verarbeitet wird und die alle dann dadurch beendet werden (so wie die beiden subVIs). Das funktionierte bisher auch problemlos.
Nun hatte ich gestern den Fall, dass ich von einem subVI ein Event auslösen wollte, dass vom Hauptprogramm aus verarbeitet werden soll (sonst löste nur das HP ein Event aus, dass von allen subVIs aus bearbeitet wurde).
Also muss ich nun mal probieren, dass so zu machen, wie Du es mir vorgeschlagen hast.
Kannst Du mir vielleicht in diesem Zusammenhang auch nochmal eine andere Möglichkeit nennen, wie ich ein subVI, dass auch eine Eventstruktur beinhaltet, beenden kann, ohne ein Ereignis "Beenden" auszulösen? In einem anderen Thread hast Du mir mal geschrieben, dass es nicht schön ist, ein VI "abzubrechen", sondern es sollte sauber beendet werden, und das finde ich auch viel besser so.
01.07.2013, 15:54 (Dieser Beitrag wurde zuletzt bearbeitet: 01.07.2013 15:56 von GerdW.)
ganz einfach: im TimeOut-Event die FGV abfragen, mit der du das Stopp-Flag weiterleitest...
(Und nicht vergessen, auch eine vernünftige TimeOut-Zeit vorzugeben!)
P.S.:
Grundregel im Umgang mit Events: ein Event immer nur in einer einzigen Eventstruktur abarbeiten (und "registrieren"/anmelden/auswählen). Die Referenz für dynamische Events fällt auch in diese Kategorie...
herzlichen Dank dafür, dass Du Dir Zeit genommen hast, mir weiterzuhelfen. Auf die Idee, in den Eventstrukturen eine timeout-Zeit zu setzen, eine FGV abzufragen und dort auch ein Beenden mit auszulösen - darauf bin ich bisher noch garnicht gekommen. Vor einiger Zeit bekam ich halt den Hinweis mit den Benutzerevents.
User Events zu nutzen ist prinzipiell richtig. Du hast hierbei nur den Fehler gemacht die Registrierung wieder zu benutzen. Das führt zu nicht vorhersagbarem Verhalten, also NIE machen. Du musst stattdessen die Eventreferenz weitergeben und für jede Ereignisstruktur neu registrieren. Der FGV-Vorschlag ist letztendlich ne Polling-Lösung und daher ist eigentlich ein sauberer Eventansatz vorzuziehen.
02.07.2013, 10:28 (Dieser Beitrag wurde zuletzt bearbeitet: 02.07.2013 13:22 von Lucki.)
Der "Irrsinn" des Programms besteht ja darin, dass das gesamte Programm nicht nur von Haupt-VI aus, sondern auch von jedem SubVI beendet werden soll. Ich wüßte kein praktisches Beispiel, in dem so etwas sinnvoll sein könnte. Damit wird das Programm umständlicher als es sein müsste. Aber natürlich läßt es sich machen. Für gewöhnlich wird der Stop-Knopf am SubVI benutzt, und dieses selbst zu schließen. Nur der Stop-Knopf am HauptVI beendet das ganze Programm.
(01.07.2013 18:49 )Holy schrieb: Der FGV-Vorschlag ist letztendlich ne Polling-Lösung und daher ist eigentlich ein sauberer Eventansatz vorzuziehen.
Ich bin auch so ein Anhänger der reinen Lehre, der nicht gern pollt. Und wozu Globals oder FGVs verwenden, wenn es Melder gibt, die schön brav warten und nicht gepollt werden müssen? (Verwende im Beispiel der Einfachheit halber statt Melder die Occurrence = nicht mehr empfohlene Primitivausführung eines Melders)
Edit: Es geht auch ohne Melder, nur mit Ereignsistrukturen.
Wir haben 3 VIs, und wenn eines beendet werden, muss das als benutzerdefinirtes Ereignis an die beiden anderen VIs gesendet werden. Das Problem ist dabei, dass, wenn das Ereignis bei einem der beiden noch geöffneten VIs ausgeführt wird, das Ereignis aus der Queue entfernt wird und sich am anderen noch geöffneten VI ereignismäßig nichts mehr tut.
Einfache pragmatische Lösung: Das benutzerdefinierte Ereingnis "Beenden" zweimal senden: Main1.vi (Größe: 8,1 KB / Downloads: 129)
(02.07.2013 10:28 )Lucki schrieb: ...
Wir haben 3 VIs, und wenn eines beendet werden, muss das als benutzerdefinirtes Ereignis an die beiden anderen VIs gesendet werden. Das Problem ist dabei, dass, wenn das Ereignis bei einem der beiden noch geöffneten VIs ausgeführt wird, das Ereignis aus der Queue entfernt wird und sich am anderen noch geöffneten VI ereignismäßig nichts mehr tut.
Einfache pragmatische Lösung: Das benutzerdefinierte Ereingnis "Beenden" zweimal senden:
Das ist nicht korrekt. Jede Registrierung stellt eine eigene Queue dar und erhält jeden gefeuerten Event für sich. Somit kannst du einen Event feuern und alle Stellen die diesen Event separat registriert haben erhalten diesen auch. Problem an Hassenfuss seinem Beispiel war die Wiederverwendung einer Registrierung und somit war das Element in der Eventqueue jeweils schon verarbeitet.
Anzeige
02.07.2013, 19:00 (Dieser Beitrag wurde zuletzt bearbeitet: 02.07.2013 19:06 von Lucki.)
(02.07.2013 18:21 )Holy schrieb: Das ist nicht korrekt. Jede Registrierung stellt eine eigene Queue dar und erhält jeden gefeuerten Event für sich. Somit kannst du einen Event feuern und alle Stellen die diesen Event separat registriert haben erhalten diesen auch. Problem an Hassenfuss seinem Beispiel war die Wiederverwendung einer Registrierung und somit war das Element in der Eventqueue jeweils schon verarbeitet.
Tatsache ist zunächst, dass das VI funktioniert, und zwar zuverlässig. Es ist alles richtig was Du sagts, aber wo soll genau die Stelle in meinem VI sein, in der etwas "nicht korrekt" ist?
Ich bringe die Vis noch in einer verbesserten Version. Der Mangel war die fehlende Skalierbarkeit. D.h. das Vi funktionierte mit den 2 SubVIs, aber bei Erweiterung auf N SubVIs, die ja alle geschlossen werden müssen, hätte man die Ereignisstrukturen jedes Mal anpassen müssen.
Daaillierte Beschreibung des Stop-Vorganges:
Bei allen VIs (MainVI und beliebige viele SubVIs) gibt es den Ereigniscase „ Stopp“ für den lokalen StopKnopf. Dieser beendet das Vi, aber nicht ohne vorher noch das benutzerdefinierte Ereignis „StopExtern“ zu generien:
.
Diese benutzerdfiniete Ereigns kann in allen noch geöffneten VIs gleichermaßen verarbeitet werden. Es ist Zufall, welches dieser VIs das Ereignis annimmt und sich dabei ebenfalls schließt.
Die restlichen VIs blieben aber geöffnet – so funktionierts also nicht.
Die Lösung des Problems: Bei der Eventbehandlung „StoppExtern“ wird das VI beendet, vorher aber das Event „StoppExtern“ erneut generiert:
Das verursacht dann das Schließen eines weiteren, zufällig ausgewählten VIs.
Wenn das letzte VI geschlossen wird, erzeugt das zwar immmer noch einen neues Event „StoppExtern“, das geht aber dann ins Leere, weil die gesamte Aplikation geschlossen ist.
(02.07.2013 18:21 )Holy schrieb: Das ist nicht korrekt. Jede Registrierung stellt eine eigene Queue dar und erhält jeden gefeuerten Event für sich. Somit kannst du einen Event feuern und alle Stellen die diesen Event separat registriert haben erhalten diesen auch. Problem an Hassenfuss seinem Beispiel war die Wiederverwendung einer Registrierung und somit war das Element in der Eventqueue jeweils schon verarbeitet.
Tatsache ist zunächst, dass das VI funktioniert, und zwar zuverlässig. Es ist alles richtig was Du sagts, aber wo soll genau die Stelle in meinem VI sein, in der etwas "nicht korrekt" ist?
Das ganze erneute Event auslösen ist nicht notwendig. Ich hab das mal entsprechend angepasst. Jetzt erzeugt ein drücken des jeweiligen STOP-Buttons den EXIT Event für alle laufenden VIs. Dieser Event beendet dann ALLE Schleifen. Weiterhin habe ich das erneute senden von Events rausgelöscht weil nicht notwendig.
Warum ist das so:
"Create User Event" erzeugt einen Event und gibt die Referenz darauf zurück. Mittels dieser Referenz kann man von überall Events auslösen. Um Events abfangen zu können muss man eine Eventreferenz mittels "Register for Events" registrieren. Dies erzeugt letztendlich eine Eventqueue in der jeder mittels der Eventreferenz gefeuerten Events einläuft. Eine Eventstruktur mit dynamischen Event Terminal kann diese abarbeiten.
Jetzt ist es möglich die Eventreferenz an mehreren "Register for Events" zu registrieren. Jedes ist eine eigene Eventqueue die jeweils jeden der gefeuerten Events bekommt. D.h. im speziellen Fall jede der Registrierungen bekommt den einen gefeuerten EXIT Event und kann diesen abarbeiten.
User Events sind letztendlich ein MIMO-System da man an mehreren Stellen Events erzeugen kann und diese an mehreren Stellen wieder abfangen kann.
Du kannst das mal mit meinem Code probieren. Zieh das SubVI noch 5mal rein und es wird trotzdem funktionieren. Das ganze erneute senden ist einfach nicht notwendig.
03.07.2013, 06:32 (Dieser Beitrag wurde zuletzt bearbeitet: 03.07.2013 09:19 von Lucki.)
Danke, Holy, es funktioniert einwandfrei. So hatte ich es eigentlich versucht zu machen, aber bei mir funktionierte das nicht, es wurden nicht alle VIs geschlossen.
Allerdings war da ein kleiner Unterschied: Die Ereiginsregistrierung erfolgt jetzt in den SubVIs einzeln. Als ich das vergeblich versucht hatte, waren die VIs noch so wie bei Hasenfuß: Ereignisregistrierung nur im HauptVI und Anschließen der Ereignis-Referenz an die SubVIs. Komisch, aber das macht wohl doch einen Unterschied.
Ja, und zwar einen erheblichen. Den Hintergrund habe ich in den Vorgängerposts entsprechend versucht zu beschreiben. Was bleibt ist folgender allgemeiner Rat.