myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Wie auf Methode einer anderen Klasse warten bevor die aufrufende Methode weiter ausgeführt wird?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

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

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Brymax
myCSharp.de-Mitglied

Dabei seit: 27.04.2018
Beiträge: 8
Entwicklungsumgebung: Visual Studio 2017 (Community)


Brymax ist offline

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

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
29.11.2018 08:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.390
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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).
29.11.2018 09:10 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Brymax
myCSharp.de-Mitglied

Dabei seit: 27.04.2018
Beiträge: 8
Entwicklungsumgebung: Visual Studio 2017 (Community)

Themenstarter Thema begonnen von Brymax

Brymax ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

C#-Code:
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 ;)

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Brymax am 29.11.2018 09:30.

29.11.2018 09:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
LaTino LaTino ist männlich
myCSharp.de-Poweruser/ Experte

avatar-4122.png


Dabei seit: 03.04.2006
Beiträge: 2.975
Entwicklungsumgebung: Rider / VS2019 / VS Code
Herkunft: Thüringen


LaTino ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LaTino am 29.11.2018 10:36.

29.11.2018 10:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.353
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
29.11.2018 11:55 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Brymax
myCSharp.de-Mitglied

Dabei seit: 27.04.2018
Beiträge: 8
Entwicklungsumgebung: Visual Studio 2017 (Community)

Themenstarter Thema begonnen von Brymax

Brymax ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.
29.11.2018 12:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.174
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 ;-)
29.11.2018 12:16 Beiträge des Benutzers | zu Buddylist hinzufügen
Brymax
myCSharp.de-Mitglied

Dabei seit: 27.04.2018
Beiträge: 8
Entwicklungsumgebung: Visual Studio 2017 (Community)

Themenstarter Thema begonnen von Brymax

Brymax ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 ;)
29.11.2018 12:32 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.353
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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
29.11.2018 13:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Brymax
myCSharp.de-Mitglied

Dabei seit: 27.04.2018
Beiträge: 8
Entwicklungsumgebung: Visual Studio 2017 (Community)

Themenstarter Thema begonnen von Brymax

Brymax ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 :)
29.11.2018 13:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.174
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Brymax:
Laut einem StackOverflow Beitrag ist es möglich.

 Beitrag

Hast Du Dir den Beitrag überhaupt angeschaut? verwundert

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.
29.11.2018 13:52 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 11 Monate.
Der letzte Beitrag ist älter als 11 Monate.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 15.11.2019 20:56