0

Ich verwende die example von Microsoft, die Daten von mehreren URLs unter Verwendung von Async und Tasks herunterlädt.Herunterladen von Webseiteninhalten unter Verwendung von Async

Meine Anforderung ist es, den Download von 200 Links in 1 Minute abzuschließen, so dass in der zweiten Minute der gleiche Satz von 200 URLs erneut heruntergeladen wird. Mir ist bewusst, dass dies im Wesentlichen von der Netzwerkgeschwindigkeit und weniger von der CPU-Leistung abhängt, da dies kein IO-gebundener Prozess ist.

Angenommen, Netzwerk und CPU würden diese Operation unterstützen und wäre kein Flaschenhals, ich sehe tatsächlich Timeout und Abbruch Ausnahme nach einiger Zeit für die Aufgaben.

Frage ist daher, im selben Beispiel, kann ich dies zu lang laufenden Aufgaben ändern, so dass die Aufgaben nicht Timeout? Ich bin mir bewusst über die Verwendung der enum und unter Verwendung LongRunning. Die Probleme sind jedoch: 1) Wie stelle ich diesen Parameter beim Erstellen der Aufgaben im folgenden Beispiel und den bereitgestellten Link zur Verfügung? 2) Was ist die Definition LongRunning? Bedeutet dies, dass jede Aufgabe keine Zeitüberschreitung mehr hat? 3) Kann ich eine unendliche Zeitüberschreitung explizit durch einen anderen Mittelwert festlegen?

Grundsätzlich ist meine Anforderung, wenn der Downloadvorgang einer bestimmten URL abgeschlossen ist, wird es erneut den Download der gleichen URL auslösen - was bedeutet, dass die gleiche URL immer und immer wieder heruntergeladen wird und daher sollte die Aufgabe nie Vollständig (die URLs im MSDN-Beispiel sind nicht die URLs, die ich auslösen werde, es wird andere URLs geben, deren Inhalt sich jede Minute ändert und daher muss ich die URL mindestens einmal pro Minute fortlaufend herunterladen).

den Code auch hier aus dem obigen Beispiel Link einfügen:

Dim cts As CancellationTokenSource 
Dim countProcessed As Integer 

Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) 

    ' Instantiate the CancellationTokenSource. 
    cts = New CancellationTokenSource() 

    resultsTextBox.Clear() 

    Try 
     Await AccessTheWebAsync(cts.Token) 
     resultsTextBox.Text &= vbCrLf & "Downloads complete." 

    Catch ex As OperationCanceledException 
     resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf 

    Catch ex As Exception 
     resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf 
    End Try 

    ' Set the CancellationTokenSource to Nothing when the download is complete. 
    cts = Nothing 
End Sub 

Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs) 
    If cts IsNot Nothing Then 
     cts.Cancel() 
    End If 
End Sub 

Async Function AccessTheWebAsync(ct As CancellationToken) As Task 

    Dim client As HttpClient = New HttpClient() 

    ' Call SetUpURLList to make a list of web addresses. 
    Dim urlList As List(Of String) = SetUpURLList() 

    ' ***Create a query that, when executed, returns a collection of tasks. 
    Dim downloadTasksQuery As IEnumerable(Of Task(Of Integer)) = 
     From url In urlList Select ProcessURLAsync(url, client, ct) 

    ' ***Use ToList to execute the query and start the download tasks. 
    Dim downloadTasks As List(Of Task(Of Integer)) = downloadTasksQuery.ToList() 

    Await Task.WhenAll(downloadTasks) 
    'Ideally, this line should never be reached 
    Console.WriteLine("Done") 

End Function 

Async Function ProcessURLAsync(url As String, client As HttpClient, ct As CancellationToken) As Task(Of Integer) 
    Console.WriteLine("URL=" & url) 
    ' GetAsync returns a Task(Of HttpResponseMessage). 
    Dim response As HttpResponseMessage = Await client.GetAsync(url, ct) 

    ' Retrieve the web site contents from the HttpResponseMessage. 
    Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync() 
    Interlocked.Increment(countProcessed) 
    Console.WriteLine(countProcessed) 
    Return urlContents.Length 
End Function 

Private Function SetUpURLList() As List(Of String) 

    Dim urls = New List(Of String) From 
     { 
      "http://msdn.microsoft.com", 
      "http://msdn.microsoft.com/en-us/library/hh290138.aspx", 
      "http://msdn.microsoft.com/en-us/library/hh290140.aspx", 
      "http://msdn.microsoft.com/en-us/library/dd470362.aspx", 
      "http://msdn.microsoft.com/en-us/library/aa578028.aspx", 
      "http://msdn.microsoft.com/en-us/library/ms404677.aspx", 
      "http://msdn.microsoft.com/en-us/library/ff730837.aspx", 
      "http://msdn.microsoft.com/en-us/library/hh290138.aspx", 
      "http://msdn.microsoft.com/en-us/library/hh290140.aspx" 
    'For space constraint I am not including the 200 URLs, but pls assume the above list contains 200 URLs 
    } 

    Return urls 
End Function 

Antwort

2

Frage ist daher im gleichen Beispiel kann ich dies zu lange laufenden Aufgaben ändern, damit die Aufgaben Timeout nicht ?

Aufgaben selbst nicht Timeout. Was Sie wahrscheinlich sehen, ist die Zeitüberschreitung der HTTP-Anforderungen. Lang laufende Aufgaben haben keine unterschiedliche Timeout-Semantik.

Ich kenne die Verwendung der TaskCreationOptions enum und LongRunning.

Sie sollten auch beachten, dass sie fast nie verwendet werden sollten.

Sie erhalten wahrscheinlich Timeouts, weil alle Ihre Anfragen die gleiche Website erreichen. Versuchen Sie die Einstellung ServicePointManager.DefaultConnectionLimit auf int.MaxValue und möglicherweise auch auf HttpClient.Timeout.

+0

Thx Stephen. Ich denke, 'ServicePointManager.DefaultConnectionLimit' hat den Trick gemacht. Natürlich habe ich auch den 'HttpClient.Timeout' gesetzt, aber keinen Unterschied mit und ohne es bemerkt. Aber ich bekomme jetzt zufällig Fehler beim Lesen des Streams. "Meine Vermutung ist wegen der Verbindung zu dem Strom, der zwischen dem Zeitpunkt der Anfrage und dem Lesen geschlossen wird. In solchen Situationen wäre meine Anforderung zu warten, sagen wir 20 Sekunden und versuchen es dann erneut Aber dann würde das 'HttpClient'-Objekt eine Zeitüberschreitung haben. Irgendwelche Vorschläge, wie ich den Code so strukturieren sollte, dass ich es auch ohne Zeitüberschreitung wiederholen kann? – Kallol

+0

Sie können' Task.Delay' erwarten und dann 'Get *' erneut aufrufen. Ich empfehle die Verwendung einer Bibliothek wie Polly für Wiederholungsversuche in Produktionsqualität. –

Verwandte Themen