且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

全部使用httpclient时取消不返回过去

更新时间:2023-02-16 21:18:24

问题是在发生异常(或您的情况下取消)时,您不会释放信号量。这意味着 Task.WhenAll 正在等待永远无法完成的任务,因为它们正在等待该信号量。

The problem is that you don't release the semaphore when there's an exception (or cancellation in your case). That means Task.WhenAll is waiting for tasks that will never complete since they are waiting for that semaphore.

将信号的释放移动到 Finally 块,以确保它从未被跳过:

Move the semaphore's release to a Finally block to make sure it's never skipped:

Async Function GetUrl(url As String, ByVal ct As CancellationToken) As Task
    Try
        ct.ThrowIfCancellationRequested()
        Await concurrencySemaphore.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}
        ct.ThrowIfCancellationRequested()
        Dim responseMessage As HttpResponseMessage = Await httpClient.GetAsync(url, ct).ConfigureAwait(False)
        Dim response As String = Await responseMessage.Content.ReadAsStringAsync()
        For Each cook As Cookie In cookies.GetCookies(baseAddress)
            Console.WriteLine(cook.Name & "=" & cook.Value)
        Next
        httpClient.Dispose()
    Catch tx As TaskCanceledException
        Console.WriteLine("Task Cancelled Exception")
    Catch ox As OperationCanceledException
        Console.WriteLine("Operation Cancelled Exception")
    Finally
        concurrencySemaphore.Release()
    End Try
End Function