1

我一定是做错了什么,因为这段代码是阻塞的并且是同步运行的,尽管调用asyncGetStringAsync. 任何帮助都会真正帮助我理解原因:

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
4

2 回答 2

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 并不熟悉。

于 2014-12-31T20:39:53.970 回答
0

这是现在完整的工作代码 - 感谢@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
于 2014-12-31T21:15:27.463 回答