httpclient.GetStringAsync阻塞

时间:2014-12-31 19:04:51

标签: vb.net async-await dotnet-httpclient asynchttpclient

我必须做错事,因为这段代码阻塞并同步运行,尽管调用了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

2 个答案:

答案 0 :(得分:1)

您的代码没有阻止,它只是顺序的。您正在触发每个Async操作,并在开始下一个Await之前异步等待它完成url

如果您要同时触发所有这些操作,请首先使用AwaitTask.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 一次创建所有这些任务:

{{1}}

*我希望这段代码有意义,因为我并不熟悉VB.Net。

答案 1 :(得分:0)

现在这里是完整的工作代码 - thx到@ l3arnon for fire all并等待所有完成。

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