Laden...

(A)Sync HttpWebRequest.GetResponse(): Wieso muss für ein separater Thread aufgemacht werden?

Erstellt von KBH vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.875 Views
KBH Themenstarter:in
13 Beiträge seit 2016
vor 6 Jahren
(A)Sync HttpWebRequest.GetResponse(): Wieso muss für ein separater Thread aufgemacht werden?

Hallo ihr Lieben,

ich habe eine Frage:

In Getting the Response of a Asynchronous HttpWebRequest wird gezeigt, wie asynchron eine Antwort angefordert wird.

Was ich mich jetzt Frage: Wieso muss für .{Begin,End}GetResponse() ein separater Thread aufgemacht werden?

Z.B. weißt in Synchronous/Asynchronous HAS NOTHING TO DO WITH MULTI-THREADING. der Autor explizit darauf hin, dass (a)sync nichts mit threading zu tun hat.

Warum brauche ich überhaupt diese {Begin,End}GetResponse - Methoden?

Wird bei dem Aufruf


HttpWebRequest request = HttpWebRequest.Create(/*url*/) as HttpWebRequest;
using(HttpWebResponse response = request.GetResponse() as HttpWebResponse /* <-- here */)
{ /* stuff */ }

nicht gewartet, bis die Response voll da ist ?

Ich vergleiche das ein wenig mit


string s = File.ReadAllText(/*fullPath*/*)

Wenn die Datei sehr groß ist, dann hängt dieser Block eben ein wenig, aber der Leseprozess bricht nicht einfach mittendrin ab.

Versteht ihr was ich meine? Oder ist es noch zu wirr, weil es für mich selbst noch zu wirr ist. 🤔

Danke und Gruß
KBH

Don't ask for easier tasks ... ask for better skills.

F
10.010 Beiträge seit 2004
vor 6 Jahren

Da hast einfach nicht verstanden wofür Async gedacht ist.

Wenn die Datei sehr groß ist, dann hängt dieser Block eben ein wenig, aber der Leseprozess bricht nicht einfach mittendrin ab.

Genau das wollen wir vermeiden, das der UI Thread hängt und der Benutzer denkt das die SW abgestürzt ist.

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo

Wird bei dem Aufruf

HttpWebRequest request = HttpWebRequest.Create(/*url*/) as HttpWebRequest;  
using(HttpWebResponse response = request.GetResponse() as HttpWebResponse /* <-- here */)  
{ /* stuff */ }  
  

nicht gewartet, bis die Response voll da ist ?

Doch.

Ich vergleiche das ein wenig mit

string s = File.ReadAllText(/*fullPath*/*)  

Wenn die Datei sehr groß ist, dann hängt dieser Block eben ein wenig, aber der Leseprozess bricht nicht einfach mittendrin ab.

Korrekt. GetResponse verhält sich genauso.

Nur wer BeginGetResponse sagt, muss auch EndGetResponse sagen. Das ist dann eben asynchron, und Du wirst per Callback informiert wenn die Response geladen ist.
Damit erreichst Du, dass die aufrufende Methode nicht blockiert wird während die Response geladen wird.

Mittlerweile würde man das aber ehen über async/await lösen (die Methode GetResponseAsync ist seit .NET 4.5 vorhanden):

HttpWebRequest request = HttpWebRequest.Create(/*url*/) as HttpWebRequest;
using(HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)
{ /* stuff */ }

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

KBH Themenstarter:in
13 Beiträge seit 2016
vor 6 Jahren

Hallo MarsStein,

das klingt alles sehr vernünftig, ich versuche nur gerade ein Beispiel zu konzentrieren, um den Unterschied besser herauszuarbeiten, gerade bzgl. der Begrifflichkeiten Methode und blockieren.

Im folgenden Code wird an der markierten Stelle (fetch response) gewartet bis die Antwort da ist, d.h. der responseString wird beschrieben und anschließend gibt die Methode eben jenen zurück


public string GetResponseString()
{
  string responseString = null;
  HttpWebRequest request = HttpWebRequest.Create(/*url*/) as HttpWebRequest;
  using(HttpWebResponse response = request.GetResponse() as HttpWebResponse /* <-- fetch response*/)
  {
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
      responseString = reader.ReadToEnd());
    }
  }
  return responseString;
}

Jetzt kann ich die Code mittels


using(HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse)

modifizieren.

Bedeutet dies nun, dass die aufrufende Methode GetResponseString den mit null initialisierten string zurückgibt, da die Funktion GetResponseAsync ... wie sagt man jetzt ... "in einem eigenen thread / detached ... was heißt an dieser Stelle asynchron?

Du schreibst ja selbst dass die aufrufende Methode nicht blockiert wird während die Response geladen wird.

Aber leider muss die aufrufende Funktion warten, d.h. blockieren, da sie etwas von der Response zurückgeben soll.

Ich kann mir dabei vorstellen, dass man bei dem asynchronen Aufruf eben eine callback Funktion mitgibt, die z.B. den string in eine Datei schreibt.
Dann ist der aufrufenden Funktion egal wann die Respnse fertig ist, da mit dem callback mitgegeben wird, was in diesem Falle zu tun ist.

So in etwa? 🤔

Gruß
KBH

Don't ask for easier tasks ... ask for better skills.

W
955 Beiträge seit 2010
vor 6 Jahren

Du schreibst ja selbst dass die aufrufende Methode nicht blockiert wird während die Response geladen wird. Er meint dass der GUI-Thread nicht blockiert wird. Es wäre sinnvoll wenn du dich erst einmal allgemein mit diesem Thema auseinandersetzen würdest.

D
985 Beiträge seit 2014
vor 6 Jahren

Wenn du innerhalb der Methode mit await hantierst, dann musst du die Methode auch als async deklarieren.

Somit wird aus

public string GetResponseString()
{
    string result;
    result = ...
    return result;
}

ein

public async Task<string> GetResponseStringAsync()
{
    string result;
    result = await ...
    return result;
}

KBH Themenstarter:in
13 Beiträge seit 2016
vor 6 Jahren

Alles klar.

Danke an alle Beteiligten.

Don't ask for easier tasks ... ask for better skills.