Events mehrfach abgefeuert?



  • Hi, ich habe ein kleines Problem... suche schon seit Stunden nach der Ursache und wollte deshalb mal ein paar Leute fragen die davon garantiert mehr Ahnung haben als ich 😉
    Also Folgendes:
    Ich habe 3 Formulare: Den Editor, den Handler und den Viewer. Der Viewer läuft in einem eigenen Thread, und feuert wenn er geschlossen wird das "ReturnValue"-Event ab, welches der Handler empfängt. Dieser verarbeitet den erhaltenen Wert und feuert seinerseits das "ReturnValue2"-Event ab um einen weiteren Wert an den Editor zu schicken...
    So weit so gut, ich erhalte im Editor sobald ich den Viewer schliesse den Wert den "ReturnValue" abgefeuert hat.
    Wenn ich den Launcher nun aber neu starte und wieder schliesse, erscheinen bei mir 2 MessageBoxes statt einer die den Wert verkünden.
    Also beim ersten starten und beenden erhalte ich eine einzige Nachricht mit dem korrekten Wert,
    beim zweiten mal erhalte ich 2 Nachrichten mit dem neuen Wert,
    beim dritten mal erhalte ich 3 Nachrichten mit dem dritten Wert usw...

    Nun könnte ich folgende Events nach dem ersten zwar einfach ignorieren, aber es ist ja nicht im sinne des Erfinders mir meinen Speicher mit einer nachher endlosen Liste an Events vollzukleistern, nicht wahr? 😉

    Habt ihr eine Ahnung woran da Liegen könnte?

    Vorweg schonmal möchte ich noch sagen, dass ich den Thread, auf dem der Viewer läuft mit einem auf OnClose des Viewers gehookten Event abbreche.

    Hier noch ein paar wichtige Ausschnitte aus dem Code:

    //Erstellen des Threads
            public void ShowInfoList()
            {
                if (Launcher.cardInfoViewerThreadGestartet == false)
                {
                    //CardInfoviewer existiert noch nicht -> Starten
                    //(Thread ist statischer Member des Hauptformulars)
                    Launcher.cardInfoViewerThread = new Thread(new ThreadStart(RunCardInfoViewerThread));
                    Launcher.cardInfoViewerThread.Start();
                    Launcher.cardInfoViewerThreadGestartet = true;
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("Eine Instanz des CardInfoViewers läuft bereits!");
                }
            }
    
    //Erstellen des Formulars
            private void RunCardInfoViewerThread()
            {
                using (cardInfoViewer = new CardInfoViewer())
                {
                    cardInfoViewer.ReturnValueEvent += new ReturnValueEventHandler(OnReceiveValue);
                    cardInfoViewer.OnCloseEvent += new EventHandler(OnCardInfoViewerClose);
                    cardInfoViewer.ShowDialog();
                }
            }
    
    //Wenn der Viewer beendet wird
            private void OnCardInfoViewerClose(object sender, EventArgs e)
            {
                lock (sender)
                {
                    cardInfoViewer.Invoke(new ThreadAbortCallback(AbortThread));
                }
    
            }
    
            private void AbortThread()
            {
                Launcher.cardInfoViewerThreadGestartet = false;
                Launcher.cardInfoViewerThread.Abort();
                Launcher.cardInfoViewerThread = null;
            }
    

    Ich hoffe wirklich das diesmal jemand eine Antwort weiss... ich bin wirklich aufgeschmissen^^
    😞

    grüße,
    Patrick



  • Mit

    cardInfoViewer.ReturnValueEvent += new ReturnValueEventHandler(OnReceiveValue);
    

    fügt der Viewer bei jedem Start ein neues Delegate in die Invokationliste ein. Und jetzt rate mal wie man den Event wieder aus der Liste austraegt?

    cardInfoViewer.ReturnValueEvent -= new ReturnValueEventHandler(OnReceiveValue);
    


  • Hm... Ich bin eigentlich davon ausgegangen dass die Invokationsliste gelöscht wird, wenn der CardInfoViewer aufgelöst wird. Dispose wurde nämlich jedes mal aufgerufen (automatisch nachdem der using-Block verlassen wird)..
    Aber natürlich ...



  • Moment mal o.O kommando zurück --- Funktioniert nicht^^

    wenn ich

    using (cardInfoViewer = new CardInfoViewer())
                {
                    cardInfoViewer.ReturnValueEvent += new ReturnValueEventHandler(OnReceiveValue);
                    cardInfoViewer.OnCloseEvent += new EventHandler(OnCardInfoViewerClose);
                    cardInfoViewer.ShowDialog();
                    cardInfoViewer.ReturnValueEvent -= new ReturnValueEventHandler(OnReceiveValue);
                    cardInfoViewer.OnCloseEvent -= new EventHandler(OnCardInfoViewerClose);
                }
    

    schreibe, ist der fehler noch immer da...

    und wenn ich

    using (cardInfoViewer = new CardInfoViewer())
                {
                    if (Launcher.EventsAdded == false)
                    {
                        cardInfoViewer.ReturnValueEvent += new ReturnValueEventHandler(OnReceiveValue);
                        cardInfoViewer.OnCloseEvent += new EventHandler(OnCardInfoViewerClose);
                    }
                    Launcher.EventsAdded = true;
                    cardInfoViewer.ShowDialog();
                }
    

    schreibe, also die events nur beim ersten mal hinzufüge, erhalte ich beim Aufruf des Events einen Fehler,

    protected override void OnClosed(EventArgs e)
            {
                ReturnValueEvent(this, new CardHandler.ReturnValueEventArgs(num));//<---Hier NullReferenceexception
                OnCloseEvent(this, new EventArgs());
                this.Dispose();
            }
    

    😞 Aber eigentlich muss der Fehler ja beim Aufruf des Formulars liegen... Wenn ich das ReturnValue Event nämlich einzeln, in einem button oder so, aufrufe, funktioniert es einwandfrei. Ich bekomme für das x-te mal dass ich das Formular aufrufe X meldungen...



  • Ah 😃

    -.- sry hatte vergessen die zweite Übergabe auch zurückzusetzen^^
    Wie ich dachte WIRD die Invokationsliste vom Viewer gelöscht... aber nicht die vom Handler. Der bleibt nämlich 😃

    Hast mir trotzdem sehr geholfen^^ danke..


Anmelden zum Antworten