C# - Eine Methode/Funktion im Hintergrund ohne zu warten ausführen.

  • C#
  • .NET (FX) 4.0

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von xChRoNiKx.

    C# - Eine Methode/Funktion im Hintergrund ohne zu warten ausführen.

    Hallöchen,

    habe hier ein Problem was wahrscheinlich kein Problem ist mir aber gerade völlig die Blockade reinhaut.
    Ich möchte eine Void aufrufen die daten an den Server per Post sendet.
    Das ist ja kein Problem und super machbar.

    Nunja ich habe diese void hier: #

    C#-Quellcode

    1. public void send_data_to_server (string datas)
    2. {
    3. var request = (HttpWebRequest)WebRequest.Create("https://xxxxxxxxx/xxxxxx.php");
    4. var postData = "enc_msg=" + datas;
    5. var data = Encoding.ASCII.GetBytes(postData);
    6. request.Method = "POST";
    7. request.ContentType = "application/x-www-form-urlencoded";
    8. request.ContentLength = data.Length;
    9. using (var stream = request.GetRequestStream())
    10. {
    11. stream.Write(data, 0, data.Length);
    12. }
    13. var response = (HttpWebResponse)request.GetResponse();
    14. var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
    15. }


    Das funktioniert und ist super. Ja es gibt andere Dinge um ein POST Request zu senden aber das ist nebensächlich.
    Nun möchte ich diese void callen OHNE das auf diese gewartet wird.
    ich dachte mir ich hau da nen async mit rein allerdings bringt das ohne await ja nichts und ich möchte ja nicht warten.
    Ich würde die gerne einfach callen und die wird ausgeführt ohne das ich darauf warten muss.
    Denn in der Zeit wo ich jetzt darauf warte passieren andere dinge die dann verschluckt werden.
    Einen neuen Thread erstellen habe ich versucht nur habe ich dann einen Konvertierungsfehler:

    Quellcode

    1. ​Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    2. Fehler CS1503 Argument "1": Konvertierung von "void" in "System.Threading.ThreadStart" nicht möglich.


    Bei diesem Code:

    C#-Quellcode

    1. ​Thread t = new Thread(send_data_to_server(Base64Encode(output_msg)));


    Also habt ihr eine Lösung dazu ?
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Der Parameter wird erst beim Starten des Threads übergeben, nicht bereits beim Konstruieren des Thread-Objekts.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Kann mit dem Begriff "Parameterized Thread" so spontan nichts anfangen, aber das könnte schon hinkommen.

    Bezogen auf dein Beispiel hätte ich das so gelöst:

    C#-Quellcode

    1. public void send_data_to_server (object datas)
    2. {
    3. ...
    4. }
    5. Thread t = new Thread(send_data_to_server);
    6. t.Start(Base64Encode(output_msg));


    Die Lösung von Murdoc nimmt den Umweg über einen anonymen Delegaten, damit umgeht man das Problem, dass der Thread-Start-Parameter vom Typ object sein muss. Ich persönlich finde das aber unübersichtlicher. Ist aber Geschmackssache.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Ich weiß, das hat nichts mit dem Lösen des Problems zu tun, dennoch möchte ich das mal Anmerken:
    "Eine Void aufrufen"?

    Zwar gibt es in VB.NET den unterschied zwischen Sub und Function, in C# ist jedoch alles eine Method oder Function, unabhängig vom Rückgabetyp.

    Ansonsten müsste man ja auch sagen: "Ich rufe eine String auf", oder gar "ich rufe eine Liste von Task von IEnumerable von integer auf".
    Nicht nur ist das grammatikalisch evtl. falsch, es macht auch ohne jeglichen Kontext keinen Sinn bzw. kann falsch verstanden werden.
    Stattdessen einfach, "Ich rufe eine Funktion/Methode auf", zu sagen, egal ob sie nun was zurück gibt oder nicht, ist für jeden klar verständlich.
    Und wenn man nun richtig Haare spalten möchte:
    Methode vs. Funktion
    Heyho,

    ha danke @EaranMaleasi.
    Ich war tatsächlich beim Erstellen des Posts am überlegen wie ich es nun nenne.
    Da ich dachte es wäre falsch das ganze Funktion zu nennen weil nichts zurück kommt.
    Aber danke für die Aufklärung.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    ich hau da nen async mit rein allerdings bringt das ohne await ja nichts und ich möchte ja nicht warten

    Hast du es ausprobiert oder ist das eine Annahme deinerseits?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Heyho,

    weder noch. Ist das was ich bei MSDN las. Das wenn ich eine Methode/Funtkion mit async deklariere aber dann ohne await nutze
    läuft sie im mainthread und es wird dann auf sie gewartet. Mit await aufrufen ist ja das gleiche nur das der mainthread nicht einfriert.

    Wenn ich den MSDN Artikel richtig verstanden habe.
    Bitte korrigiert mich wenn ich falsch liege nicht das ich was falsches annehme und lerne 8|
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Probier es aus. Ich bin der Meinung, dass das await nicht zwingend notwendig ist.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Heyho,

    genau. Das sagte ich ja auch. Es geht auch ohne await nur dann wird der mainthread blockiert und dadurch
    automatisch andere operationen geblockt.

    mit await wird ein nebenthread gestartet allerdings auf die Beendigung dieses gewartet.
    Aber ich kann es gerne nachher nochmal testen. Denke aber mal das da die MSDN Info schon richtig ist.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Wenn ich mich recht entsinne, macht await nix anderes als ein Flag (quasi) zu setzen um, wenn die Methode (läuft asynchron) durchgelaufen ist, an diese Stelle zu springen und den nachfolgenden Code auszuführen. Ohne await wird die Methode (asynchron) ausgeführt und der nachfolgende Code wird dann direkt ausgeführt.

    Ich lasse mich da jedoch gerne auch eines Besseren belehren :)
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Heyho,
    bei folgendem Code:

    C#-Quellcode

    1. private void button1_Click(object sender, EventArgs e)
    2. {
    3. testAsync();
    4. MessageBox.Show("test");
    5. }
    6. public async void testAsync ()
    7. {
    8. for (int i = 0; i < 50000 ; i++)
    9. {
    10. Console.WriteLine(i);
    11. }
    12. }


    kommt die messagebox erst nachdem bis 50k gezählt wurde in der for schleife.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Ich weiß ja nicht, wie das bei C# ist, aber fehlt da nicht bei der async-Prozedur irgendwo ein await?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Heyho @VaporiZed,

    ehm ich denke das ist das dingen was ich noch nicht ganz verstehe bei async/await.....

    Wenn ich es so mache:

    Spoiler anzeigen

    C#-Quellcode

    1. private async void button1_Click(object sender, EventArgs e)
    2. {
    3. await testAsync();
    4. MessageBox.Show("test");
    5. }
    6. public async Task testAsync ()
    7. {
    8. for (int i = 0; i < 50000 ; i++)
    9. {
    10. Console.WriteLine(i);
    11. }
    12. }



    den Button_Click async und die Methode als Task async dann kann ich await im button click nutzen
    und die messagebox kommt während des zählens ohne das gewartet wird das der Task fertig wird...

    Nun verstehe ich gar nichts mehr glaub ich... :P Hat jemand sehr gute Async/Await Lektüre für mich ?
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen
    Zu async und await muss man sich lediglich folgendes merken:
    Wenn ich eine Funktion als async deklariere, dann will ich in dieser Funktion auf etwas mit await warten. Habe ich nichts zum warten, macht async keinen sinn.

    Diese Funktion:

    C#-Quellcode

    1. public async Task testAsync ()
    2. {
    3. for (int i = 0; i < 50000 ; i++)
    4. {
    5. Console.WriteLine(i);
    6. }
    7. }

    sollte jedoch erst garnicht kompilieren, da noch kein Task zurückgegeben wurde.
    Ebenso ist async hier unnötig, da hier nicht gewartet wird.
    Mach das async weg, pack um die Schleife einen Task, und gib diesen zurück, dann kannst du auf diese Methode mit await warten.

    await ist, soweit mir bekannt, extrem süßer syntaktischer zucker für Task.ContinueWith(), da es sich nun auch hervorragend mit try-catch versteht (anstatt wie bisher irgendwelche AggregateExceptions auswerten zu müssen)

    Tasks an und für sich sind eigentlich etwas sehr geniales. Anders als ein Thread läuft ein Task nämlich zunächst im selben Thread wie alles andere, jedoch concurrent, d.h. innerhalb des selben Threads wird die CPU Zeit mal für einen Task, mal für den anderen benutzt, sodass eine GUI und eine Berechnung nebeneinander her laufen können, ohne separate Threads zu haben, was es außerordentlich einfach macht wieder zurück zu kehren. Erkennt die Runtime nun, dass dieser Task lange andauert, oder nun wirklich viel CPU-Zeit benötigt, wird der Task auf einen extra Thread ausgelagert, um die maximale Performance zu bekommen, bzw. um den anderen Thread so wenig wie möglich zu stören.

    Und nun kommt async/await ins Spiel.
    Dank diesen beiden Schlüsselwörtern kann in C# wunderbar lesbar und ohne Gedankliche Knoten um Invoken usw., asynchron programmiert werden.
    Ob Thread oder nicht Thread ist nun völlig egal. Was auch immer man mit await erwartet geschieht neben der Ausführung der GUI, und wenn man nach dem await ist, befindet man sich wieder im Kontext der GUI.
    Die Runtime nimmt einem das Multithreading einfach ab. Der code sagt klar, dass ich hier warte, und erst danach mit dem nachfolgendem Code fortfahren möchte.
    @EaranMaleasi sehr sehr großes Dankeschön für die Erklärung.
    Ich denke ich habs dann auch gerafft.

    Werde morgen mal ein wenig mehr was damit machen um ganz rein zu kommen.
    Wirklich sehr großes danke das du dir die Zeit für soviel Text genommen hast.

    Die Funktion kompiliert übrigens super ohne Fehler.
    Grüße , xChRoNiKx

    Nützliche Links:
    Visual Studio Empfohlene Einstellungen | Try-Catch heißes Eisen

    xChRoNiKx schrieb:

    mit await wird ein nebenthread gestartet allerdings auf die Beendigung dieses gewartet.
    Nein, weder await noch async starten irgendwelche Threads. Das musst du schon selber machen oder auf eine Framework-Methode awaiten, die intern einen Task startet.

    xChRoNiKx schrieb:

    und die messagebox kommt während des zählens ohne das gewartet wird das der Task fertig wird...
    Bei mir nicht. Gibt ja auch keinen Task, das läuft alles Synchron.