Wie funktionieren C # Events im Hintergrund?
Ich bin mit C#, .NET 3.5. Ich verstehe, wie er Ereignisse, wie deklarieren Sie in meiner Klasse zu, wie Sie Haken Sie von woanders, etc. Ein erfundenes Beispiel:
public class MyList
{
private List<string> m_Strings = new List<string>();
public EventHandler<EventArgs> ElementAddedEvent;
public void Add(string value)
{
m_Strings.Add(value);
if (ElementAddedEvent != null)
ElementAddedEvent(value, EventArgs.Empty);
}
}
[TestClass]
public class TestMyList
{
private bool m_Fired = false;
[TestMethod]
public void TestEvents()
{
MyList tmp = new MyList();
tmp.ElementAddedEvent += new EventHandler<EventArgs>(Fired);
tmp.Add("test");
Assert.IsTrue(m_Fired);
}
private void Fired(object sender, EventArgs args)
{
m_Fired = true;
}
}
Jedoch, was ich tun nicht verstehen, wenn man erklärt einen event-handler
public EventHandler<EventArgs> ElementAddedEvent;
Es ist nie initialisiert - also, was, genau, ist ElementAddedEvent? Was hat es zu zeigen? Im folgenden wird nicht funktionieren, weil der Event-Handler wird nie initialisiert:
[TestClass]
public class TestMyList
{
private bool m_Fired = false;
[TestMethod]
public void TestEvents()
{
EventHandler<EventArgs> somethingHappend;
somethingHappend += new EventHandler<EventArgs>(Fired);
somethingHappend(this, EventArgs.Empty);
Assert.IsTrue(m_Fired);
}
private void Fired(object sender, EventArgs args)
{
m_Fired = true;
}
}
Ich merke, dass es ein Event-Handler.CreateDelegate(...), aber alle Signaturen vorschlagen, dieses dient nur zur Befestigung Delegierten zu einem bereits vorhandenen Event-Handler durch die typischen ElementAddedEvent += new EventHandler(MyMethod).
Ich bin mir nicht sicher, ob was ich versuche zu tun, wird helfen,... aber eigentlich würde ich gern kommen mit einer abstrakten übergeordneten DataContext in LINQ, deren Kinder registrieren können, welche Tabellentypen Sie wollen "beobachtet" also ich kann schon Veranstaltungen wie BeforeUpdate und AfterUpdate, sondern bestimmte Typen. So etwas wie dieses:
public class BaseDataContext : DataContext
{
private static Dictionary<Type, Dictionary<ChangeAction, EventHandler>> m_ObservedTypes = new Dictionary<Type, Dictionary<ChangeAction, EventHandler>>();
public static void Observe(Type type)
{
if (m_ObservedTypes.ContainsKey(type) == false)
{
m_ObservedTypes.Add(type, new Dictionary<ChangeAction, EventHandler>());
EventHandler eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler;
m_ObservedTypes[type].Add(ChangeAction.Insert, eventHandler);
eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler;
m_ObservedTypes[type].Add(ChangeAction.Update, eventHandler);
eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler;
m_ObservedTypes[type].Add(ChangeAction.Delete, eventHandler);
}
}
public static Dictionary<Type, Dictionary<ChangeAction, EventHandler>> Events
{
get { return m_ObservedTypes; }
}
}
public class MyClass
{
public MyClass()
{
BaseDataContext.Events[typeof(User)][ChangeAction.Update] += new EventHandler(OnUserUpdate);
}
public void OnUserUpdated(object sender, EventArgs args)
{
//do something
}
}
Sich Gedanken über gemacht mich erkennen, dass ich nicht wirklich verstehen, was vorgeht unter der hod mit Veranstaltungen - und ich würde das gerne verstehen 🙂
InformationsquelleAutor der Frage Matt | 2008-10-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich geschrieben habe, diese in eine Menge von Details in einen Artikelaber hier ist die Zusammenfassung, vorausgesetzt, Sie sind einigermaßen zufrieden mit die Delegierten sich:
Für Feld-wie bei den Ereignissen, gibt es einige Synchronisation aber ansonsten ist das hinzufügen/entfernen, rufen Sie einfach Delegieren.Kombinieren/Entfernen um den Wert zu ändern die automatisch generierten Feld. Diese beiden Vorgänge weisen Sie dem Feld sichern - denken Sie daran, dass die Delegierten sind unveränderlich. In anderen Worten, der automatisch generierte code ist sehr ähnlich wie diese:
Den anfänglichen Wert des erzeugten Feldes in Ihrem Fall ist
null
- und es wird immernull
wieder, wenn alle Teilnehmer entfernt, so dass das Verhalten der Delegierten.Entfernen.Wenn Sie möchten, eine "no-op" - handler zu abonnieren, die zu Ihrer Veranstaltung, so wie zur Vermeidung der Nichtigkeit überprüfen, die Sie tun können:
Den
delegate {}
ist nur eine anonyme Methode, die kümmert sich nicht um seine Parameter und tut nichts.Wenn es etwas gibt, dass noch immer unklar ist, bitte Fragen und ich werde versuchen zu helfen!
InformationsquelleAutor der Antwort Jon Skeet
Unter der Haube, Veranstaltungen sind nur Teilnehmer mit speziellen Aufrufkonventionen. (Zum Beispiel, Sie don ' T müssen überprüfen, ob die Nichtigkeit vor dem auslösen einer Falle.)
In pseudocode, Event.Invoke () - bricht wie diese:
Wenn Ereignis-Listener
Rufen jeden listener synchron auf diesen thread, in beliebiger Reihenfolge.
Da Ereignisse sind multicast, Sie haben null oder mehr Zuhörer, statt in einer Sammlung. Die CLR wird eine Schleife durch Sie, indem Sie jedes in beliebiger Reihenfolge.
Einer großen Einschränkung zu erinnern ist, dass event-Handler ausführen, die in dem gleichen thread wie das Ereignis ausgelöst wird. Es ist eine gemeinsame mentale Fehler zu denken, als Sie erzeugt einen neuen thread. Das tun Sie nicht.
InformationsquelleAutor der Antwort Yes - that Jake.