GetStringAsync vorzeitig abbrechen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Manfred_62.

    GetStringAsync vorzeitig abbrechen

    Hallo zusammen,

    ich möchte ein GetStringAsync vorzeitig abbrechen wenn es Probleme mit der Verbindung gibt. Automatisch wird nach etwa 38 Sekunden mit einem Fehler beendet. Das würde ich gerne verkürzen. Jedoch finde ich keine Möglichkeit dazu ;( Oder geht das gar nicht?

    Zum besseren Verständnis der Codeteil:

    VB.NET-Quellcode

    1. Try
    2. Dim myHttpClient As HttpClient = New HttpClient()
    3. Dim sScriptContent As String = Await myHttpClient.GetStringAsync(sMyScriptURL & sMyScriptFileDownload & "?Command=" & sCommand & "&Content=" & sContent & "&Param0=" & sParam0)
    4. Dim sRecords As String() = sScriptContent.Split(sRecordSeparators, StringSplitOptions.RemoveEmptyEntries) 'Datensätze trennen


    Die Zeile 3 hängt manchmal bis zu 38 Sekunden. Die Exception sagt dann, dass keine Verbindung aufgebaut werden kann. Soll so sein.
    Kann mir jemand einen Hinweis geben ob ich die Antwortzeit verkürzen kann und in welche Richtung das gehen muss (nach einem Tag entnervtem suchen und testen :love: ).

    LG
    Manfred
    Z.B. Asynchronously wait for Task<T> to complete with timeout

    Bei diesem Beispiel startest du, so wie ich das verstanden habe, 2 Tasks. Einmal den mit deiner Aufgabe und dann einen Task.Delay und je nachdem welcher zuerst zurück kommt, kannst du dann reagieren.
    @Manfred_62 Probierma

    VB.NET-Quellcode

    1. myHttpClient.Dispose()
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich würde das mit einem CancellationToken angehen:

    C#-Quellcode

    1. var client = new HttpClient();
    2. var cancellationTokenSource = new CancellationTokenSource();
    3. cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(5)); // Timeout Dauer hier
    4. try
    5. {
    6. var response = await client.GetAsync("<URL HERE>", cancellationTokenSource.Token);
    7. string responseString = await response.Content.ReadAsStringAsync();
    8. Console.WriteLine("Antwort:");
    9. Console.WriteLine(responseString);
    10. }
    11. catch (TaskCanceledException)
    12. {
    13. // Hier landet man, wenn der Client zu lange braucht
    14. Console.WriteLine("Timed out.");
    15. }
    16. finally
    17. {
    18. cancellationTokenSource.Dispose();
    19. client.Dispose();
    20. }


    Durch das Token wird die GetAsync(..) Methode automatisch nach einer bestimmten Dauer abgebrochen. Im Standardfall wird dann eine TaskCanceledException geworfen, die du abfangen kannst.


    Das ganze kannst du durch eine Erweiterungsmethode noch verkürzen (Fehlerbehandlung fehlt noch):

    C#-Quellcode

    1. public static async Task<string> GetStringAsync(this HttpClient httpClient, string url, CancellationToken token)
    2. {
    3. var response = await httpClient.GetAsync("<URL HERE>", token);
    4. return await response.Content.ReadAsStringAsync();
    5. }
    6. // Und noch kürzer, basierend auf oberer Extension-Method
    7. public static async Task<string> GetStringAsync(this HttpClient httpClient, string url, int msecTimeout)
    8. {
    9. var tokenSource = new CancellationTokenSource(msecTimeout);
    10. try
    11. {
    12. return await httpClient.GetStringAsync(url, tokenSource.Token);
    13. }
    14. catch (TaskCanceledException ex)
    15. {
    16. tokenSource.Dispose();
    17. throw ex;
    18. }
    19. }
    20. // Methode 1
    21. var tokenSource = new CancellationTokenSource();
    22. tokenSource.CancelAfter(TimeSpan.FromSeconds(5));
    23. await client.GetStringAsync("<URL HERE>", tokenSource.Token);
    24. // Methode 2
    25. await client.GetStringAsync("<URL HERE>", 5000);
    Danke für eure Anregungen.

    @petaod
    @shad

    Das war die Richtung die ich gesucht hatte :)

    Sieht jetzt so aus und funktioniert prima ... nach 2 Sekunden wird abgebrochen

    VB.NET-Quellcode

    1. Try
    2. Dim myHttpClient As HttpClient = New HttpClient()
    3. Dim sTimeSpan As New TimeSpan(0, 0, 2)
    4. myHttpClient.Timeout = sTimeSpan
    5. Dim sScriptContent As String = Await myHttpClient.GetStringAsync(sMyScriptURL & sMyScriptFileDownload & "?Command=" & sCommand & "&Content=" & sContent & "&Param0=" & sParam0)
    6. Dim sRecords As String() = sScriptContent.Split(sRecordSeparators, StringSplitOptions.RemoveEmptyEntries) 'Datensätze trennen


    LG
    Manfred

    Manfred_62 schrieb:

    Dim sTimeSpan As New TimeSpan(0, 0, 2)
    Wohl ein Grund mehr, warum Microsoft in den Coding Conventions schreibt Do not use Hungarian notation.
    Für Timespan gibt es in der ungarischen Notation kein Prefix.
    Aber s ist definitv falsch (weil irreführend), da es für Strings reserviert ist.

    Ganz elegant kannst du es umgehen, wenn du gar keine Variable verwendest: ;)

    VB.NET-Quellcode

    1. myHttpClient.Timeout = New TimeSpan(0, 0, 2)
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --