httpclient.GetStringAsync阻塞(httpclient.GetStringAs

2019-10-21 12:23发布

我必须做一些错误的,因为这个代码是阻塞和同步运行,调用的inspite async方法GetStringAsync 。 任何帮助将真正帮助我理解的原因:

Private Async Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
    Dim urls As List(Of String) = SetUpURLList()
    Dim baseAddress = New Uri("http://www.amazon.com")
    ServicePointManager.DefaultConnectionLimit = 10
    Dim requestNumber As Integer = 0
    For Each url In urls
        requestNumber += 1
        Console.WriteLine("Request #:{0}", requestNumber)
        Dim cookies As New CookieContainer()
        Dim handler As New HttpClientHandler With {.CookieContainer = cookies, _
                                                   .UseCookies = True}
        Dim httpClient = New HttpClient(handler) With {.BaseAddress = baseAddress}
        Dim response As String = Await HttpClient.GetStringAsync(url).ConfigureAwait(False)
        For Each cook As Cookie In cookies.GetCookies(baseAddress)
            Console.WriteLine(cook.Name & "=" & cook.Value)
        Next
        httpClient.Dispose()
    Next

    Console.WriteLine("Done")
End Sub

Answer 1:

您的代码没有阻止,只是顺序。 你是射击每个Async操作,异步地等待它完成与Await开始下一个之前。

如果你想同时发射所有这些操作首先要建立每个任务url ,然后Await一次使用所有这些任务Task.WhenAll

Dim semaphore As New SemaphoreSlim(10)
Async Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
    Dim urls As List(Of String) = SetUpURLList()
    ServicePointManager.DefaultConnectionLimit = 10
    Dim tasks As List(Of Task) = new List(Of Task)()
    For Each url In urls
        tasks.Add(GetUrlAsync(url))
    Next
    Await Task.WhenAll(tasks)
    Console.WriteLine("Done")
End Sub

Async Function GetUrlAsync(url As String) As Task
    Await semaphore.WaitAsync()
    Dim baseAddress = New Uri("http://www.amazon.com")
    Dim cookies As New CookieContainer()
    Dim handler As New HttpClientHandler With {.CookieContainer = cookies, _
                                               .UseCookies = True}
    Dim httpClient = New HttpClient(handler) With {.BaseAddress = baseAddress}
    Dim response As String = Await HttpClient.GetStringAsync(url).ConfigureAwait(False)
    For Each cook As Cookie In cookies.GetCookies(baseAddress)
        Console.WriteLine(cook.Name & "=" & cook.Value)
    Next
    httpClient.Dispose()
    semaphore.Release()
End Sub

*我希望这个代码是有道理的,因为我不是很熟悉VB.Net。



Answer 2:

这里现在是完整的工作代码 - THX,以@ l3arnon消防所有等待了在所有完成。

Dim concurrencySemaphore As New SemaphoreSlim(10)
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim urls As List(Of String) = SetUpURLList()
    ServicePointManager.DefaultConnectionLimit = 10 'Not working strangely
    Dim tasks As List(Of Task) = New List(Of Task)()
    For Each url In urls
        tasks.Add(GetUrl(url))
    Next
    Await Task.WhenAll(tasks)
    Console.WriteLine("Done")
End Sub
Async Function GetUrl(url As String) As Task
    concurrencySemaphore.Wait()
    Dim baseAddress = New Uri("http://www.amazon.com")
    Dim cookies As New CookieContainer()
    Dim handler As New HttpClientHandler With {.CookieContainer = cookies, _
                                               .UseCookies = True}
    Dim httpClient = New HttpClient(handler) With {.BaseAddress = baseAddress}
    Dim response As String = Await httpClient.GetStringAsync(url).ConfigureAwait(False)
    For Each cook As Cookie In cookies.GetCookies(baseAddress)
        Console.WriteLine(cook.Name & "=" & cook.Value)
    Next
    httpClient.Dispose()
    concurrencySemaphore.Release()
End Function


文章来源: httpclient.GetStringAsync blocking