2015-06-23 201 views
3

我嘗試驗證我的圖像網址以查看它們是否有效。我有這麼多人,需要幾個小時才能完成這項任務。因此,我決定以異步方式進行。我想知道下面的代碼是否有很大的區別或優勢。使用Parallel.ForEach與/或異步/等待

我的主要功能是:使用異步

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)等待。使用利用並行的foreach和asnyc並行的foreach

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

3)

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

2)/等待

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

第三個可能是最好的解決方案,但它不會讓我在ForEach內呼叫Await/Async

如果我用的是第二個,testurl函數具有異步HTTP調用,但不能與Await,thereofore它與異常消息崩潰:

[TaskCanceledException:一個任務被取消]

上線myHttpClient.GetAsync。我猜測它會拋出這個異常,因爲ForEach已經結束,請求取消,但httpclient還沒有完成它的工作。如果這可能是最好的解決方案,我該如何處理?

或者任何其他解決方案,使我的工作更快。

+0

這可能是TPL數據流,它提供與異步支持粗糙Parallel.ForEach功能良好的任務。 –

+0

它是新的,只支持4.5及更高版本? – batmaci

+1

@batmaci就像'async/await',是的 –

回答

8

你肯定不想用Parallel.ForEachParallel用於在多個內核上傳播CPU綁定算法,這將不會爲您帶來任何好處(在您的方案中,您的算法不受CPU限制)。

實際上你想要的是併發性,而不是並行性。異步併發可以用Task.WhenAll做到:

Dim tasks = myImages.Select(Function(x) testUrl_async(x)) 
Dim results = Await Task.WhenAll(tasks) 
+0

我的第一個方法與每個經典方法和同步等待之間有很大的性能(速度)差異嗎? – batmaci

+0

我測試過,它有很大的不同。感謝您的幫助:) – batmaci

+0

您可以好好看看我的其他後連接到這個職位的文章呢?我不想問更多的問題,而是我創建了一個新帖子。 http://stackoverflow.com/questions/31027885/how-can-i-control-thread-count-when-i-use-task-whenall – batmaci