2015-06-23 204 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