1

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
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へのthx。

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 に答える