使用 Parallel.ForEach with/or async/await

using Parallel.ForEach with/or async/await

我尝试验证我的图片 URL 以查看它们是否有效。我有太多这样的人,以至于要花几个小时才能完成这项任务。因此,我决定异步进行。我想知道按如下方式执行我的代码是否有任何重大差异或优势。

我的主要职能是:

Async Function testUrl_async(ByVal myImageurl As String) As Task(Of Boolean)

   myHttpResponse = Await myHttpClient.GetAsync(myImageurl)
    If myHttpResponse.IsSuccessStatusCode Then
        mySuccess = True
    Else
        mySuccess = False
    End If

    Return mySuccess
End Function

 Function testUrl(ByVal myImageurl As String) As  Boolean

   myHttpResponse = myHttpClient.GetAsync(myImageurl)
    If myHttpResponse.IsSuccessStatusCode Then
        mySuccess = True
    Else
        mySuccess = False
    End If

    Return mySuccess
End Function

1) 使用异步等待。

For Each myImage In myImages
    Dim result=await testUrl_async(myImageUrl).Result 
    'some code                  
Next

2) 使用并行 foreach

Parallel.ForEach(myImages, 
    Sub(myImage)
        testUrl(pictureComponent.websiteShop.hqpatronen, myImageUrl) 
        'some code
    End Sub)

3) 使用并行 foreach 和 asnyc/await

Parallel.ForEach(myImages, 
    Sub(myImage)
        await testUrl_async(pictureComponent.websiteShop.hqpatronen, myImageUrl) 
    'some code
    End Sub)

第三个可能是最好的解决方案,但它不允许我在 ForEach 中调用 Await/Async

如果我使用第二个,testurl 函数有异步 http 调用,但没有 Await,因此它崩溃并显示异常消息:

[TaskCanceledException: A task was canceled.]

在调用 myHttpClient.GetAsync 的行上。我猜它抛出这个异常是因为 ForEach 已经结束并且请求取消但是 httpclient 还没有完成它的工作。如果这是最好的解决方案,我该如何处理?

或者可以让我的工作更快的任何其他解决方案。

你肯定不想使用Parallel.ForEachParallel 用于在多个内核上传播 CPU 绑定算法,这不会给您带来任何好处(在您的场景中,您的算法不是 CPU 绑定)。

你真正想要的是并发,而不是并行。异步并发可以使用Task.WhenAll:

来完成
Dim tasks = myImages.Select(Function(x) testUrl_async(x))
Dim results = Await Task.WhenAll(tasks)