Лучший способ планирования асинхронного httpClient - PullRequest
0 голосов
/ 28 мая 2020

У меня есть список URL-адресов, которые нужно очищать каждую минуту, а затем сохранять на жестком диске. Теперь я использую таймер и разделил список URL-адресов на более мелкие пакеты. В каждом тике таймера я жду асинхронного c метода, чтобы получить этот меньший пакет URL-адресов, как показано ниже:

 Private Async Sub timerGetData_Tick(sender As Object, e As EventArgs) Handles timerGetData.Tick
    tickCounter += 1
    Dim UrlPorcessed_Tick, failedUrl_Tick As Integer, StartTime_Round As String
    If tickCounter > tickNum Then
        tickCounter = 1
        roundCounter += 1      ' one round of getting all urls, i.e 1 minute
        processedUrlCounter = 0
        failedUrlCounter = 0
        UrlPorcessed_Tick = 0
        failedUrl_Tick = 0
        StartTime_Round = Now.TimeOfDay.ToString

        FailedUrls = New List(Of String)
        FailedUrlsReason = New List(Of String)
    End If


    Dim firstIndex, lastIndex As Integer
    firstIndex = (tickCounter - 1) * TickUrlsNum
    lastIndex = If(firstIndex + TickUrlsNum - 1 > AllUrlsNum - 1, AllUrlsNum - 1, firstIndex + TickUrlsNum - 1)
    Dim logText As String

    For rr = firstIndex To lastIndex

        Dim r As DataRow = UrlsDt(rr)

        Dim address As String = r("url")
        Dim strFull As String = ""
        Try
            strFull = Await GetTseData(address2)
        Catch ex As TaskCanceledException
            logText = ex.ToString
        End Try

        If strFull = String.Empty Then
            failedUrl_Tick += 1
            FailedUrls.Add(address)
            FailedUrlsReason.Add("Empty response" & " -- t1: " & t1 & "  -- t2: " & t2)
            Continue For
        End If

       Dim r2 As Integer = FillDb(dbFile, address, strFull)
        If r2 = 0 Then
            failedUrl_Tick += 1
            FailedUrls.Add(address)
            FailedUrlsReason.Add("Problem in Url Process")
            Continue For
        End If

        UrlPorcessed_Tick += 1
    Next

    processedUrlCounter += UrlPorcessed_Tick
    processedUrlCounter_Total += UrlPorcessed_Tick
    failedUrlCounter += failedUrl_Tick
    failedUrlCounter_Total += failedUrl_Tick

    logText = StartTime_GetData + vbNewLine + "-------------------" + vbNewLine + _
             "round time: " + StartTime_Round + vbNewLine + _
              "round counter: " + roundCounter.ToString + vbNewLine + _
             "tick counter: " + tickCounter.ToString + vbNewLine + _
             "All Urls Number:" + AllUrlsNum.ToString + vbNewLine + _
              "from/to:" + firstIndex.ToString + "/" + lastIndex.ToString + vbNewLine + _
             "Urls processed (in round)/Total:" + processedUrlCounter.ToString & "/" & processedUrlCounter_Total & vbNewLine & _
             "Urls failed (in round)/Total:" + failedUrlCounter.ToString & "/" & failedUrlCounter_Total & vbNewLine & _
             "failed percentage (in round)/Total:" & Math.Round(failedUrlCounter / (failedUrlCounter + processedUrlCounter) * 100, 1).ToString & "/" & Math.Round(failedUrlCounter_Total / (failedUrlCounter_Total + processedUrlCounter_Total) * 100, 1).ToString & vbNewLine

    If tickCounter = tickNum Then
                    logText += vbNewLine & "Unsuccessful Urls: " & vbNewLine
        For i = 0 To FailedUrls.Count - 1
            logText += FailedUrls(i) & ", " & FailedUrlsReason(i) & vbNewLine
        Next
        System.IO.File.AppendAllText(logFile, logText)
    End If



End Sub

Это метод, который получает данные из inte rnet:

Private Async Function GetData(address As String) As Task(Of String)

    Dim response As HttpResponseMessage = Await hc.GetAsync(address)
    Dim Str = Await response.Content.ReadAsStringAsync()
    If response.IsSuccessStatusCode Then
        Return Str
    Else
        Return ""
    End If

End Function

и HttpClient создается в from_load. Теперь у меня такой вопрос:

  1. Эффективно ли я выполняю работу? (Мне нужно, чтобы эта операция была асинхронной c, потому что в другой части программы я читаю результат с жесткого диска)
  2. В приведенном выше коде у меня есть некоторые проблемы при успешном журналировании неудачного (= пустой ответ) URL. Это звучит из-за использования asyn c mechansim, я получаю меньшие URL-адреса в файле журнала. Скажем, все URL-адреса = 1000, я вижу 800 успешных и 100 неудачных URL-адресов в файле журнала. Как я могу решить эту проблему?
...