Erhöhung von Ereignissen im Vergleich zu direkten Methodenaufrufen

8

Wenn Sie ein Ereignis auslösen, wird der Ereignishandler aufgerufen. zB Ссылка

Was ist der Unterschied zwischen der Verwendung des Ereignismechanismus und direkten Aufrufen anderer Methoden (z. B. wenn eine Bedingung in Methode A () erfüllt ist, Aufruf B ())?

Und was ist der Unterschied zwischen dem Konsumieren und Anheben von Ereignissen?

Danke

    
dotnetdev 18.04.2010, 00:52
quelle

6 Antworten

6
  

Wenn Sie ein Ereignis auslösen, wird das Ereignis aufgerufen   Handler

Das hat falsch angefangen. Es könnte einen no Event-Handler geben. Oder viele. Du weißt es nicht. Was ist der Hauptunterschied zum direkten Aufruf einer Methode? Suchen Sie nach "Beobachtermuster" in Ihrem Lieblingsdesignmusterbuch.

    
Hans Passant 18.04.2010, 02:16
quelle
18

Der Unterschied ist:

Methodenaufruf ="Mach dieses spezielle Ding"

Event raise ="Wenn jemand zuhört und sich kümmert, ist diese Sache einfach passiert."

Es ist von zentraler Bedeutung für die Trennung von Bedenken und die Wiederverwendbarkeit. Eine Schaltfläche ist keine wiederverwendbare Komponente, wenn sie durch Anklicken eine bestimmte Methode aufruft. Aber wenn es einfach zu dem Programm "ankündigt", auf das es geklickt wurde, und interessierte Parteien dafür verantwortlich sind, sich selbst zu abonnieren, ist es unendlich wiederverwendbar.

Die zugrundeliegende technische Implementierung, wie dies erreicht wird (über den Delegierten), ist irrelevant.

    
Rex M 18.04.2010 03:03
quelle
2

Wenn Sie ein Ereignis auslösen (oder aufrufen, um den Begriff von Ihrem Link zu verwenden), bedeutet dies, dass Sie das Ereignis an alle Kunden senden. Zum Beispiel kann ein Fenster ein Ereignis auslösen, wenn es mit der Maus angeklickt wird.

Wenn Sie ein Ereignis konsumieren, erhalten und verarbeiten Sie das Ereignis von jedem, der es gesendet hat. Zum Beispiel möchten Sie vielleicht wissen, wann das Fenster mit der Maus angeklickt wird.

Wenn Sie nur einen Consumer haben, können Sie etwas ähnliches erreichen, indem Sie einfach einen Callback direkt bereitstellen:

%Vor%

Der Ereignismechanismus bereinigt dies etwas, indem er verhindert, dass der Konsument den Delegiertenwert direkt setzt. Stattdessen wird der Kunde sich selbst mit dem Operator += registrieren. Wenn sich der erste Verbraucher registriert, wird der Delegat festgelegt, und wenn sich der zweite Kunde registriert, werden seine beiden Rückrufe durch Delegate.Combine verkettet.

    
Eric 18.04.2010 01:56
quelle
2

Für jeden, der an der Durchführung von Event Call interessiert ist, habe ich diesen einfachen Benchmark gemacht. Es zeigt die Unterschiede zwischen dem direkten Aufruf einer Methode, dem Aufruf über die Schnittstelle, dem Delegaten und dem Ereignis, bei dem ein Handler angehängt ist.

In jedem Szenario wird die Methode in entsprechender Weise 1 000 000 000 Mal aufgerufen. Hier sind (vielleicht überraschende) Ergebnisse:

Anruf des Delegierten: 23 240 ms - der schnellste

Ereignisaufruf: 23 295 ms

Direktruf: 23 396 ms

Schnittstellenaufruf: 23 716 ms - die langsamste

Die Messungen wurden in Release Build mit C # in .NET4.0 durchgeführt.

Der Code ist hier:

%Vor%     
Matyas 02.09.2015 14:47
quelle
1
  

Was ist der Unterschied zwischen der Verwendung?   der Ereignismechanismus und direkte Anrufe   zu anderen Methoden (zB wenn eine Bedingung ist   in Methode A () getroffen, Anruf B ())?

Geschäftslogisch gibt es keinen Unterschied zwischen den beiden. Was ich damit meine, ist, dass Sie die gleiche Aufgabe in jeder Hinsicht erfüllen können. Es ist nur eine andere Art, das zu tun. Der wirkliche Unterschied ist die Menge an Arbeit, die Sie tun müssen, um die Benachrichtigung anderer Module zu handhaben.

Wenn Sie ein Ereignis auslösen, sagen Sie im Wesentlichen: "Hey, irgendwas ist passiert, irgendeinen Code, der sich angemeldet hat, um benachrichtigt zu werden, wenn das passiert ist. Welche Module benachrichtigt werden, ist nicht meine Sache, weil ich es bin vorausgesetzt, dass (zur Laufzeit) alle Module, die wissen müssen, für die Benachrichtigung eingerichtet sind. "

Wenn Sie jede Methode direkt aufrufen, treffen Sie die Entscheidung, dass Sie diesen (oder diesen) Modulen und nur diesen mitteilen, dass etwas passiert ist. Sie machen diese Behauptung, dass egal, was die Zustände dieser Module sind, nicht wichtig ist und sie wissen müssen, dass dieses Ereignis passiert ist.

Beide sind für verschiedene Situationen richtig. Ereignisbenachrichtigungen sind dynamischer. Verschiedene Module können sich für Benachrichtigungen registrieren und abmelden. Direkte Methodenaufrufe sind statischer. Eine bestimmte Menge von Objekten (oder Modulen usw.) wird absolut benachrichtigt (natürlich abgesehen von Ausnahmen), dass etwas passiert ist, aber nur diese werden benachrichtigt.

    
kemiller2002 18.04.2010 02:27
quelle
0

Zusätzlich zu den obigen Szenarien mit mehreren / keine Teilnehmer werden Ereignisse auch dazu verwendet, die Code-Kopplung zu reduzieren - zB muss die Methode A () zur Kompilierungszeit nichts über die Methode B () wissen. Dies ermöglicht eine bessere Trennung von Bedenken und weniger fragilen Code.

In der Praxis sieht man eher Ereignisse, die in Framework- und UI-Code verwendet werden, während Entwickler in der Domänenlogik einer Anwendung häufiger Dinge wie Getrennte Schnittstelle und Dependency Injection , um Code zu entkoppeln. In letzter Zeit gab es in verschiedenen Bereichen mehr Diskussionen über die Verwendung von Ereignissen innerhalb der Domänenlogik, ein Ansatz, der geschickt als Domain-Ereignisse .

    
Sam 18.04.2010 02:51
quelle

Tags und Links