我必须做错事,因为这段代码阻塞并同步运行,尽管调用了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
答案 0 :(得分: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
一次创建所有这些任务:
{{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