0

AsyncTasksを使用して複数のURLのデータをダウンロードするMicrosoftのexampleを使用しています。asyncを使用してウェブページコンテンツを並行してダウンロードする

私の要件は200分のリンクを200分ダウンロードして2分後に同じ200個のURLのセットが再びダウンロードされるようにすることです。私は、大部分がネットワーク速度に依存し、CPUの電力にはあまり依存しないことを認識しています。これはIOバインドプロセスではないためです。

ネットワークとCPUがこの操作をサポートしており、ボトルネックにはならないと仮定すると、実際にはタスクのタイムアウト後にタイムアウトとキャンセルの例外が発生しています。

質問は同じですが、これを長時間実行するタスクに変更して、タスクがタイムアウトしないようにすることはできますか?私はTaskCreationOptions列挙型の使用を認識しており、LongRunningを使用しています。ただし、問題は次のとおりです。 1)以下の例のタスクを作成するときにこのパラメータを指定する方法と、リンクを指定する方法はありますか? 2)定義LongRunningとは何ですか?これは、各タスクがもうタイムアウトしないことを意味しますか? 3)明示的に無限タイムアウトを他の何らかの方法で設定することはできますか?

基本的には、特定のURLのダウンロードプロセスが完了すると、同じURLのダウンロードが再開されます。つまり、同じURLが繰り返しダウンロードされるため、タスクは決して行われません(MSDNの例のURLは、私が起動するURLではなく、1分ごとに内容が変化する他のURLがあるため、毎分少なくとも1回URLを連続してダウンロードする必要があります)。

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 

答えて

2

質問タスクがタイムアウトしないように、そのため、同じ例では、私は長時間実行されるタスクにこれを変更することができますされています。上記の例のリンクからあまりにもここにコードを貼り付け

タスク自体はタイムアウトしません。おそらくあなたが見ているのは、HTTP要求がタイムアウトしたことです。長時間実行されるタスクは、異なるタイムアウトセマンティクスを持ちません。

私はTaskCreationOptions列挙型の使用法とLongRunningの使用について認識しています。

また、ほとんど使用しないでください。


すべての要求が同じウェブサイトをヒットしているので、あなたは、おそらくタイムアウトを取得しています。 ServicePointManager.DefaultConnectionLimitint.MaxValueに設定してください。可能であればHttpClient.Timeoutも増やしてください。

+0

Thxスティーブン。私は 'ServicePointManager.DefaultConnectionLimit'がやったと思う。もちろん、私は 'HttpClient.Timeout'を設定しましたが、それがあってもなくても、何の違いも気付かなかったのです。しかし、私は今ストリームを読んでいるランダムなエラーを取得しています。私の推測は、ストリームの要求と読んだ時間の間に閉鎖されているストリームのためです。そのような状況では、私の要件は、しかし、その後、 'HttpClient'オブジェクトはタイムアウトになります。どのようにすれば、タイムアウトすることなく再試行できるようにコードを構造化するべきですか? – Kallol

+0

' Task.Delay'を待ち、 'Get *'を再呼び出しできます。私は、プロダクション品質の再試行のためにPollyのようなライブラリを使うことをお勧めします。 –

関連する問題