2016-07-21 20 views
1

Hier Ich überprüfe für propertie wenn es migrierten oder In-Progress, Wenn In-Fortschritt dann möchte ich nicht für Web Response Nachricht warten von URL geliefert, so HttpPost Verfahren in Hintergrund laufen soll und calling method sollte seine Aufgabe ausführen gleichzeitig. Um diese Funktionalität zu erreichen, habe ich async und await in den folgenden Methoden verwendet.Wie async verwenden und in C# erwarten?

unten ist das Verfahren zum Post und XML Antwort zurück von URL-Adresse:

public static async Task<string> HttpPost(string url, string message, bool ignoreResponse = false) 
{ 
    string lcPostData = null; 
    string _XmlResponse = string.Empty; 
    try 
    {    
     using (var client = new HttpClient()) 
     { 
      var httpContent = new StringContent(message, Encoding.UTF8, "application/xml"); 
      var SupplierLinkUri = new Uri(url); 

      if (!ignoreResponse) 
      {      
       var httpResponseMessage = await client.PostAsync(SupplierLinkUri, httpContent); 

       if (httpResponseMessage.StatusCode == HttpStatusCode.OK) 
        _XmlResponse = httpResponseMessage.Content.ReadAsStringAsync().Result; 
      } 
      else if (ignoreResponse && !(isReservation(message))) //message.Contains("Reservation")) 
      {  
       /* I want below lines of code to run asynchronously (i.e. Run in background) So I used Task & await but it fails*/ 
       Task<HttpResponseMessage> httpPostTask = client.PostAsync(SupplierLinkUri, httpContent); 
       HttpResponseMessage asyncPost = await httpPostTask;     
      } 
     }  
    } 
    catch (Exception e) 
    {  
    } 
    return _XmlResponse; 
} 

Das obige Verfahren ausgeführt wird, ohne Fehler, aber ich mag wissen, ob dies ein richtiger Ansatz ist async und await in C# zu verwenden, , Muss ich meinen Code irgendwo ändern oder ist er gemäß den genannten Anforderungen korrekt?

await in else-if Teil funktioniert nicht. Laut Dokumentation sollte dies asynchronously, d. H. Im Hintergrund laufen, aber derzeit ist es nicht.

Kann jemand bitte überprüfen und schlägt vor, was im Code falsch ist?

Ist ihre bessere Möglichkeit, dies zu erreichen?

Schätzen Sie alle Vorschläge und Ideen! Danke für die Hilfe!

+0

Wenn Sie die xml in Block bekommen ks vom Server gibt es wirklich nichts, was Sie tun können, um die Daten als kontinuierliche Daten zu erhalten, wenn der Server-Code nicht geändert wird. Get Daten in Block ist wahrscheinlich effizienter als einen großen Datenblock zu erhalten, der eine Speicherausnahme verursachen kann. Riesige XML-Dateien verursachen häufig Speicherausnahmen, und dann müssten Sie einen xmlreader verwenden, der die XML-Datei effektiv in Blöcken liest, so wie Sie es gerade tun. – jdweng

+0

Was versuchst du hier zu machen - und was genau ist das Problem? Wenn das Problem darin besteht, dass Sie erst nach der Rückkehr der Aufgabe eine Antwort von dieser Methode erhalten, wird dies erwartet. – Paddy

+0

@Paddy: Problem ist, ich verwende 'erwarten', um die' client.PostAsync (SupplierLinkUri, httpContent); 'im Hintergrund an anderer Stelle wie Dokumentation, aber es läuft synchron. –

Antwort

-1

OK - dies ist nicht, wofür async/await sind - wenn Sie warten, wird die aufgerufene Methode in einem anderen Thread (nicht im UI-Thread) ausgeführt und gibt die Kontrolle an Ihre Hauptmethode zurück (über eine Fortsetzung in der Hintergrund), wenn es abgeschlossen ist.

Die Methode, auf die Sie warten, gibt ihr Ergebnis erst zurück, wenn der Async-Aufruf abgeschlossen ist.

z.B.

async Task<int> A() 
{ 
    return await B(); 
} 

async Task<int> B() 
{ 
    //Call to a long running service to get your answer, e.g. 
    return await PostToClientAsynchronously(); 
} 

//Event handler on front end. 
async void SomeButton_Click() { 
    txtBox1.Text = await A(); 
} 

In dem obigen Beispiel die PostToClientAsynchronously wird auf einem anderen Thread (nicht das UI Gewinde) ausgeführt werden, aber die Steuerung wird nicht zurückkehren Textbox den Wert in den Event-Handler bis zu setzen, nachdem der Beitrag abgeschlossen hat.

Ich möchte ein Beispiel für Ihren eigenen Code, aber um ganz ehrlich zu sein, ich bin mir nicht sicher, was genau Sie tun möchten. Ich vermute, dass das Problem dadurch gelöst werden kann, dass die asynchronen Methoden auf Ihre Benutzeroberfläche erweitert werden, also nicht blockiert und andere Vorgänge erlaubt werden, aber ich bin mir nicht sicher.

Die andere wichtige Sache beim Aufruf von async/await-Methoden ist, dass alle Methoden (vom Frontend nach unten) als async markiert werden müssen, um korrektes Warten zu ermöglichen.


Es klingt wie Sie diese als ‚fire and forget‘ Typ Methoden, aber diese sind nur dann wirklich jeder gut, wenn, was Sie tun nicht geben Informationen, die Sie anschließend auf wo sie anpacken müssen versuchen, laufen Sie sind sicher, dass eventuelle Ausnahmen Ihrer Anwendung nicht schaden. Alle aufgetretenen Ausnahmen werden nicht in Ihre Anwendung übertragen.

Echte Feuer und vergessen Anwendungsfälle sind selten.


Weitere Informationen darüber, warum es Schildkröten den ganzen Weg nach unten "sein muss, wenn Asynchron-Programmierung:

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Mehr Informationen über Feuer und vergessen (dafür, dass Sie den Abschnitt weiter lesen ' async Leere‘im vorherigen Artikel vermeiden:

Fire and Forget approach

+0

Vielen Dank für die ausführliche Erklärung! –

+0

'awaward' führt keine Methode auf einem Hintergrund-Thread aus und wird nicht notwendigerweise auf dem ursprünglichen Thread fortgesetzt (in diesem Fall wird es im Allgemeinen * nicht *). Außerdem gibt es in einer ASP.NET-App keinen UI-Thread. –

+0

@StephenCleary - Es tut uns leid, Post war nicht klar, woher dieser Anruf gemacht wurde. Ich bin mir bewusst, dass es in ASP.net keinen UI-Thread gibt und habe nicht erwähnt, dass er auf dem * selben * Thread fortgesetzt wird. – Paddy