Laden...

Wie auf Methode einer anderen Klasse warten bevor die aufrufende Methode weiter ausgeführt wird?

Erstellt von Brymax vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.807 Views
B
Brymax Themenstarter:in
22 Beiträge seit 2018
vor 5 Jahren
Wie auf Methode einer anderen Klasse warten bevor die aufrufende Methode weiter ausgeführt wird?

Hallo zusammen,

ich Programmiere gerade meinen 2ten TCP-Server nach dem Request-Response Prinzip. Mein erster TCP-Server wandelt den Stream auch gleich in einen String um und sendet diesen an eine ander Klasse die wiederum anhand des Strings die angeforderten Daten dem Server bereitstellt der wiederum die Antwort an den Client sendet.

Sprich TCP-Server -> Stream in String wandeln -> an Klasse Foo senden --> Foo String auswerten -> Antwort generieren -> an TCP Server senden -> String in Stream wandeln -> an Client senden.

Jetzt möchte ich das ganze "besser" machen.

Der TCP-Server soll die Umwandlung in einen String nicht mehr vornehmen sonder nur ein Event triggern den beliebige Klasse XYZ abonnieren kann. Als Argument erhält dann Klasse XYZ den Stream und kann damit arbeiten. Bis die Klasse XYZ fertig ist mit seiner Antwort soll der TCP-Server warten und den Task erst weiter ausführen wenn Klasse XYZ seine Arbeit verichtet hat.

Sprich TCP-Server -> Event auslösen und warten -> Klasse XYZ Stream umwandeln -> Antwort generieren -> an TCP-Server senden -> TCP-Server antwort an Client senden.

Wie kann ich hier vorgehen?

Dank euch schonmal für eure Antworten.

Grüße

Brymax

4.931 Beiträge seit 2008
vor 5 Jahren

Da brauchst du doch nichts extra programmieren, denn wenn das Ereignis (event) aufgerufen wird, dann läuft die aufrufende Methode doch erst weiter, wenn die Ereignismethode vollständig ausgeführt wurde (außer dort wird die Aufgabe an einen anderen Thread bzw. einer anderen Task weitergeleitet und nicht auf die Abarbeitung gewartet wird).

B
Brymax Themenstarter:in
22 Beiträge seit 2018
vor 5 Jahren

Vllt. mal zur Veranschaulichung die Funktion die in dem Task der Klasse TcpServer ausgeführt wird:

private void ClientRequestConnection(Socket socket)
        {
            socket.ReceiveTimeout = 5000;

            int requestLength = 0;

            byte[] requestArray = null;
            byte[] requestLengthArray = new byte[4];

            #region Empfang der Anfrage
            try
            {
                socket.Receive(requestLengthArray);

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(requestLengthArray);
                }

                requestLength = BitConverter.ToInt32(requestLengthArray, 0);
                requestArray = new byte[requestLength];

                if (requestLength > 0)
                {
                    try
                    {
                        socket.Receive(requestArray);
                        OnRequestReceived(requestArray); // <-- Event auslösen
                    }
                    catch (SocketException)
                    {
                    }
                }
            }
            catch (Exception ex)
            {
            }
            #endregion

            // Warten bis XYZ- Klasse die Antwort generiert hat

            #region Senden der Antwort
            try
            {
                // Antwort senden
            }
            catch (Exception ex)
            {
            }
            #endregion
        }

Der TcpServer löst nur das Event aus das eine andere Klasse abonniert hat. Würde dann der Task nicht einfach weiterlaufen da die Funktion ja nicht weiß ob die Funktion der XYZ-Klasse abgeschlossen ist oder nicht? Vllt. Steh ich hier auch auf dem Schlauch.

Vorher habe ich statt ein Event zu senden einfach XYZ.GetRespone() aufgerufen um die erforderliche Antwort zu erhalten.

P.S. Die leeren catch-Blöcke sind nur Platzhalter und werden später natürlich noch gefüllt 😉

3.003 Beiträge seit 2006
vor 5 Jahren

Wie Th69 schrieb: da läuft nichts nebenläufig. Wenn das Event abonniert wurde, laufen alle EventHandler durch und dann geht's erst weiter.

Sieh die Eventhandler als eine Art ausgelagerte Methode. Nur, dass man nicht weiß, wieviele es sind, und was die genau machen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

T
2.219 Beiträge seit 2008
vor 5 Jahren

Scheinbar solltest du dir das Thema Events nochmal anschauen.
Diese laufen nicht paralell sondern werden asynchron ausgeführt.
Du kannst in deiner Klasse z.B. ein OnReceive Event definieren.
Dies sollte dann den Client Socket, zum senden der Antwort, und den empfangen Datenblock erhalten.
Es sollte dem jeweiligen Event dann überlassen werden, wir es die Daten verarbeitet.
Also auch die Umwandlung in String etc.

Ansonsten wäre auch zu klären ob Events hier der richtige Ansatz ist.
Ich würde hier eher eine Klasse bauen, die intern je nach erhaltenen Daten dann die entsprechende Antwort generiert.
Geht dann schon etwas in Richtung Command Pattern.
Hier wäre dann jeder Request ein Command, der eben seine Aktionen auslöst und dann eben entsprechende Antworten generiert und zurück sendet.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

B
Brymax Themenstarter:in
22 Beiträge seit 2018
vor 5 Jahren

Dank euch mal 😃

T-Virus so in der Art ist das ganze geplant.

Was ich mir vorgestellt habe ist das der Subscriber des Events die Antwort an den TcpServer zurückliefert ohne das ich hierfür noch zusätzlich einen Methodenaufruf starten muss.

So in der Art: byte[] response = OnRequestReceived(byte[] request)

Aber ich habe mich nochmal ein bisschen schlau gelesen und Events sind wohl dafür wie du meintest nicht gedacht. Eine Rückgabewert ist hier nicht vorgesehen.

16.807 Beiträge seit 2008
vor 5 Jahren

Ein Event kann technisch auch gar nichts zurück geben; vor allem nicht generisch.
Du solltest Dir da evtl. nochmal die Grundlagen von C# anschauen 😉

B
Brymax Themenstarter:in
22 Beiträge seit 2018
vor 5 Jahren

Laut einem StackOverflow Beitrag ist es möglich.

Beitrag

Nur gibts hier Probleme welcher Wert dann entgültig zurück gegeben wird. Der der als letztes das Event abonniert hat gewinnt. Das natürlich sehr Unschön 😉

T
2.219 Beiträge seit 2008
vor 5 Jahren

An der Stelle liefert das Event keinen Rückgabewert.
Hier wird nur im übergebenen Argument die Eigenschaft gesetzt, was aber kein Rückgabewert im Sinne von Funktionen sind.

Gibt es den mehr als einen Subscriber deines Events oder wäre es nur eine Verarbeitungskette in dem ein spezifischer Request eben nur von einem spezifsche Teil der Kette verarbeitet wird?

Wenn deine Subscriber eben nur spezifische Verarbeitungen sind, nimm lieber eine Verarbeitungsmethode/Klasse die eben den spezifischen Request verarbeitet und den Response liefert.
Das wäre auch sauberer als jedem Subscriber die Daten zu geben von denen ggf. nur einer die Daten tatsächlich verarbeitet.

Gerade die Verarbeitung von Daten in einem TCP/UDP Server sollte man nicht über Events lösen.
Sinnvoll wäre es die spezifsichen Requests an spezifische Verarbeitungsklassen zu geben, die dann die Daten verarbeiten und dir eben deinen Response liefern.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

B
Brymax Themenstarter:in
22 Beiträge seit 2018
vor 5 Jahren

So läuft der erste Server der auch Produktiv im Einsatz ist und er verrichtet sein Dienst auch zuverlässig. Zugegeben die Auslastung ist bei maximal 5 angemeldeten Clients noch sehr gering.

Aktuell gibt es nur ein Subscriber aber nach deinem letzten Beitrag werde ich die Idee verwerfen und es wie bekannt umsetzen.

Ich Danke für eure Antworten mir wurde geholfen 😃

16.807 Beiträge seit 2008
vor 5 Jahren

Laut einem StackOverflow Beitrag ist es möglich.


>

Hast Du Dir den Beitrag überhaupt angeschaut? 🤔

a) können in .NET Events kein Rückgabewert haben; sondern wenn dann der Event Handler. Du arbeitest jedoch mit dem Event! Das sind Unterschiede! Das zeigt übrigens auch Dein Link.
b) gibt es in C# keine Funktionen sondern Methoden, denn C# ist eine OOP-Sprache. Funktionen hat man in prozeduralen Sprachen.

Erneuter, freundlich gemeinter Hinweis Dir die Grundlagen anzuschauen 😉

PS: eigentlich gibt es in der .NET Welt kaum noch einen Grund, einen TCP Server selbst zu schreiben und sich mit dem Handling zu ärgern.
Für fast alle Fälle gibt es abstraktionen wie zB. ASP.NET Core. Die Wahrscheinlichkeit, dass Dein Ansatz unnötig ist, ist schon hoch - aber Du erzählst leider nichts von Deinem Szenario.