Funktion ist abhängig von Event

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Funktion ist abhängig von Event

    Hallo zusammen,

    ich habe mal eine Frage bezüglich Events in C#. Ich habe eine Funktion GetAufabe(), welche über einen Socket eine Nachricht an einen Server sendet mit der ID der Aufgabe. Der Server holt anhand der ID ein Aufgaben Objekt aus der Datenbank und sendet dieses zurück. Beim Client wird diese Nachricht in einem extra Thread empfangen und dann wird das Event AufgabenDataReceived ausgelöst. In den dazugehörigen EventArgs befindet sich nun meine Aufgabe, welche ich in der Funktion GetAufgabe() zurückgeben möchte.

    Gibt es in C# einen einfachen Weg die EventArgs an meine Funktion zu übergeben, oder muss ich mir diese zwangsweise nochmals separat zwischenspeichern und diese dann zurückgeben?

    C#-Quellcode

    1. EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);

    C#-Quellcode

    1. private void Srv_AufgabenDataReceived(object sender, AufgabeEventArgs e)
    2. {
    3. ewh.Set();
    4. }

    C#-Quellcode

    1. public Aufgabe GetAufgabe(long A_NR, bool istErledigteAufgabe = false)
    2. {
    3. if (!IsLoggedIn)
    4. throw new Exceptions.LoginRequiredException("Aktion erfordert Login am AufgabenServer. Bitte loggen Sie sich ein.");
    5. ServerProtokoll serverProtokoll = new ServerProtokoll();
    6. serverProtokoll.requestAufgabeNachricht = new ServerLibrary.NachrichtenTypen.RequestAufgabeNachricht(A_NR, istErledigteAufgabe);
    7. serverProtokoll.Send();
    8. ewh.WaitOne();
    9. return empfangeneAufgabe;
    10. }


    Viele Grüße,
    Marvin
    @MarvinKleinMusic Erstell ein Event mit denselben Argumenten und reiche das Event samt Argument einfach weiter.
    Als Sender trag this ein und feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    vielen Dank für deine Nachricht. Könntest du diesbezüglich vielleicht ein Beispiel geben? Mir ist nicht ganz klar, wie Ich das umsetzen soll.

    Wie soll ich dann mit diesem Event auf meine Funktion zurückführen können?


    LG Marvin
    @MarvinKleinMusic So was:

    C#-Quellcode

    1. privare void EventHandlerFromAnyWhere(object sender, AnyEventArgs e)
    2. {
    3. this.EventToCaller(this, e);
    4. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Danke für deine Antwort allerdings verstehe ich noch immer nicht, wie mir das weiterhelfen soll.

    Die Funktion GetAufgabe() sendet ja die Anfrage an den Server und wartet bis der EventWaitHandler getriggert wird.

    Das Event AufgabenDataReceived ist allerdings Teil der Klasse ServerConnection, welches dann aufgerufen wird, wenn dieser Nachrichtentyp vom Server empfangen worden ist.

    Sprich ich möchte unter ewh.WaitOne(); die Aufgabe aus den AufgabeEventArgs zurückgeben, welche ich ja gerade empfangen habe.

    Sprich ich brauche in der Funktion GetAufgabe die vor dem Event ausgeführt wird, die AufgabeEventArgs aus dem Event, sobald die Aufgabe eingetroffen ist, damit ich diese mittels return zurückgeben kann.

    Ich könnte mir die Aufgabe zwar auch einfach immer beim Eventaufruf zwischenspeichern, doch das finde ich eher Kontraproduktiv, da die Objekte zum Teil sehr groß sein können.

    LG Marvin
    Deine vom Server abgerufene Aufgabe kommt in einem völlig anderen Kontext zurück als dem, in dem die Aufgabe angefordert wurde. Und das gleich in zweifacher Hinsicht:
    1) Andere Methode, d.h. anderer Aufrufstack und damit anderer Scope
    2) Anderer Thread (!)

    Du kannst nun diverse beliebig komplizierte Konstrukte drumherum bauen, um nach außen hin den Anschein eines synchronen Aufrufs zu erwecken. Das ändert aber nichts daran, dass du die Aufgabe von dem einen in den anderen Kontext kopieren musst. Bedenke dabei, dass du sowieso nur eine Referenz kopierst - der Aufwand dafür ist minimal.

    Edit: Um die Frage zu beantworten: Hier ist eine einfache Variante mit einem Lambda-Handler. Aus oben genannten Gründen wird das Ergebnis natürlich zwischengespeichert. Das Ganze ist außerdem nur 'syntactic sugar' für einen separaten Handler zusammen mit einer globalen Variable.

    VB.NET-Quellcode

    1. Module Test
    2. Function GetAufgabe() As Aufgabe
    3. Dim mre As New ManualResetEvent(False)
    4. Dim srv As New Server
    5. Dim result As Aufgabe = Nothing
    6. Dim handler = Sub(sender As Object, e As AufgabeEventArgs)
    7. result = e.Result
    8. mre.Set()
    9. End Sub
    10. AddHandler srv.AufgabenDataReceived, handler
    11. srv.Send()
    12. mre.WaitOne()
    13. RemoveHandler srv.AufgabenDataReceived, handler
    14. Return result
    15. End Function
    16. End Module
    17. Class Aufgabe
    18. End Class
    19. Class AufgabeEventArgs
    20. Inherits EventArgs
    21. Public Property Result As Aufgabe
    22. End Class
    23. Class Server
    24. Public Event AufgabenDataReceived As EventHandler(Of AufgabeEventArgs)
    25. Public Sub Send()
    26. End Sub
    27. End Class
    Gruß
    hal2000

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „hal2000“ ()