Laden...

Events werden mehrmals aufgerufen / Events deregistrieren / Abfragen, ob Event registriert ist

Erstellt von TBR vor 12 Jahren Letzter Beitrag vor 12 Jahren 5.897 Views
Thema geschlossen
T
TBR Themenstarter:in
154 Beiträge seit 2009
vor 12 Jahren
Events werden mehrmals aufgerufen / Events deregistrieren / Abfragen, ob Event registriert ist

Hallo, ich hab grad ein Problem...

Mein Code added per Timer immer eine Methode fürs Click-Event eines Controls.
Nun bei einem Klick wird, jenachdem wie lang das Programm schon läuft immer öfters die Methode aufgerufen...

Kann man das verhindern, ohne zigtausend Variablen und if´s?

Durch das wiederholte aufrufen geht das ganze nicht gescheit ...

Danke
TBR

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo TBR,

wundert dich das Verhalten wenn die bei jedem Tick einen Event-Handler registrierst?
Oder hab ich dich falsch verstanden? Zeig mal den (relevanten) Code.
Was willst du damit erreichen?

Siehe auch [FAQ] Eigenen Event definieren / Information zu Events

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

T
TBR Themenstarter:in
154 Beiträge seit 2009
vor 12 Jahren

Ja mir ist klar dass hier der Fehler liegt.

Ich update es, denn sobald sich ein Int nicht 1 oder 2 ist sollen sich alle Handler vom Event ablösen. Wenn er wieder 1 oder 2 ist sollen sie sich wieder registrieren.

Das Problem ist, wie ich prüfe ob der Handler schon hinzugefügt worden ist 😕
Click auf null prüfen geht nicht, "=" anstatt "+=" geht nicht ...

Irgendwie muss das doch ganz einfach gehen, oder ist das etwa ein .Net Fail?

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo TBR,

wie ich prüfe ob der Handler schon hinzugefügt worden ist

Entweder du merkst du das selbst od. prüfst das per Reflektion - letzteres ist aber mehr ein Hack. Wenn das Event allerdings in einer von deinen Klassen ist kann, da es ein Delegate ist, auf die InvocationList zugegriffen werden (Delegate.GetInvocationList).

Ich update es, denn sobald sich ein Int nicht 1 oder 2 ist sollen sich alle Handler vom Event ablösen.

Warum machst du diese Prüfung nicht im Ereignishandler des Events - kannst du auch in eine Methode auslagern:


private void Button1_Click(object sender, EventArgs e)
{
    if (!this.ProcessEvent()) return;
}

private void Button2_Click(object sender, EventArgs e)
{
    if (!this.ProcessEvent()) return;
}

private bool ProcessEvent()
{
    return (myInt == 1 || myInt == 2);
}

Das ist mMn nach viel einfacher.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

T
TBR Themenstarter:in
154 Beiträge seit 2009
vor 12 Jahren

Das Problem ist, dass ich nicht weiß ob der Handler hinzugefügt ist.
Ich dachte eigentlich, das .Net den selben Delegate nur einmal ans Event bindet, bzw. nru einmal aufruft... oder wenigstens eine Möglichkeit bietet, dass man prüft ob der Delegate an das Event gebunden ist.

Aber naja, da scheitert .Net wohl noch.

Ich werds einfach mit einer Variable machen. Ich finds zwar umständlich, aber gut...

Mit Reflection möcht ichs gar nicht machen, da wär der Aufwand höher als der Sinn.

Aber danke für die Tipps 😃
MfG
TBR

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo TBR,

noch zur Erklärung: ein Event ist ein MulticastDelegate, d.h. es können soviele Targets bzw. Eventhandler wie möglich registiert werden (per +=).
Prüfen ob überhaupt ein Ereignishandler registriert ist geht "wie üblich" per != und im obigen Link auch gezeigt. Prüfen ob ein bestimmter Ereignishandler registriert ist geht von außen nicht so leicht.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

P
660 Beiträge seit 2008
vor 12 Jahren

Also wenn es wirklich nur darum geht einen EventHandler pro Control/was auch immer
zu registrieren, dann greif zu einer Dictionary<Control, EventHandler>. Wenn du ein
Event registrierst dann pack es in die Dictionary (prüfe vorher ob es schon vorhanden
ist) und wenn der Wert sich ändert dann deregistriere den EventHandler und schmeiss
es aus der Dictionary. oder nimm nur eine List<Control>.

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo TBR,

Prüfen ob überhaupt ein Ereignishandler registriert ist geht "wie üblich" per !=

allerdings auch nur innerhalb der Klasse. Von außerhalb der Klasse kann man überhaupt nur mit += und -= zugreifen. Das reicht aber normalerweise vollkommen.

Wenn man möchte, dass ein bestimmte EventHandler nicht mehr registriert ist, man aber nicht weiß, ob er momentan überhaupt registriert ist: Statt zu prüfen, ob ein bestimmter EventHandler registriert ist und ihn dann zu entfernen, entfernt man ihn einfach direkt mit -=. Im Ergebnis ist der EventHandler weg, egal ob er vorher registriert war oder nicht.

Wenn man möchte, dass ein bestimmte EventHandler registriert wird, aber nicht doppelt, falls er schon registriert ist: Statt zu prüfen, ob ein bestimmte EventHandler registriert ist und ihn nur dann zu registrieren, wenn er es noch noch nicht registriert ist, entfernt man ihn erst mit mit -= und fügt ihn dann mit += hinzu. Im Ergebnis ist der EventHandler genau einmal registriert, egal ob er vorher registriert war oder nicht.

Das ist gehört allerdings zu den Grundlagen.

Die Beschreibung geht davon aus, da jeder EventHandler nur maximal einmal registriert wurde. Erst wenn man sowas will, wie einen EventHandler nur hinzufügen, wenn er weniger als zehnmal registriert ist, muss man sich die Anzahl selber merken (oder Reflection verwenden).

herbivore

Thema geschlossen