如何控制线程数,当我使用" Task.WhenAll" [英] How can I control thread count when I use "Task.WhenAll"

查看:421
本文介绍了如何控制线程数,当我使用" Task.WhenAll"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过一个HTTP GET请求异步地验证图片网址。一切工作正常与下面的code,但是当我有这么多的图片,我们的防火墙会阻止,因为这么多线程同时请求我的网络连接。因此,我一直在寻找一个解决方案,如何限制同时运行的线程数。我结束了本<一个href=\"http://stackoverflow.com/questions/10806951/how-to-limit-the-amount-of-concurrent-async-i-o-operations\">thread告诉我要使用 SemaphoreSlim 但我不知何故无法得到的想法以及如何实现这一点?


  • 是SemaphoreSlim等待或waitAsnyc(有什么区别呢?)应该是一个foreach里面同时添加任务?我可以只创建任务列表使用LINQ正如我在code呢?

    • 为什么会出现使用task.Run?

    • 执行不线程启动后行? task.run或task.whenall后?


如果这不是最好的方法,请提出一个更好的。我不知道,如果使用MaxDegreeOfParallelism与parallel.foreach有道理呢?

 暗淡任务= myImages.Select(功能(X)testUrl_async(X))
  昏暗的结果=等待Task.WhenAll(任务)异步功能testUrl_async(MYIMAGE BYVAL作为图像)作为任务(形象)
   昏暗myImageurl作为字符串= myImage.imageurl
   myHtt presponse =等待myHttpClient.GetAsync(myImageurl)
    如果myHtt presponse.IsSuccessStatus code,则
        返回MYIMAGE
    其他
        什么都不返回
    万一
结束功能


解决方案

  

我们的防火墙会阻止,因为这么多线程同时请求我的网络连接。因此,我一直在寻找一个解决方案,如何限制同时运行的线程数。


pretty确保防火墙限制的连接的的你的电话号码,因此要限制你的连接的(不是的线程数)。


  

是SemaphoreSlim等待或waitAsnyc(有什么区别呢?)


等待是一个同步的等待 - 它阻塞调用线程。 WaitAsync 是一个异步等待 - 它释放调用线程和恢复执行当前方法时,信号量可用


  

应该是在foreach内同时加入的任务?我可以只使用LINQ创建任务列表正如我在code呢?


您可以做到这一点无论哪种方式:明确地建立一个列表,或者使用LINQ


  

为什么会出现使用task.Run?


这是在回答一个错误。 Task.Run 肯定是不需要或不想要的这里。


  

后线不执行线程开始? task.run或task.whenall后?


当你调用 Task.Run ,该委托立即排队到线程池。但正如我上面所说的,你不希望使用 Task.Run (也应该不会在原来的答案被使用,也可以)。


所以,这样的事情应该足够了:

 私人_mutex作为新SemaphoreSlim(20)
异步功能testUrl_async(MYIMAGE作为图像)作为任务(形象)
    等待_mutex.WaitAsync()
    尝试
        昏暗myImageurl = myImage.imageurl
        昏暗的myHtt presponse =等待myHttpClient.GetAsync(myImageurl)
        返回如果(myHtt presponse.IsSuccessStatus code,MYIMAGE,为Nothing)
    最后
        _mutex.Release()
    结束Try
结束功能

I am verifying image urls by making an http get request asynchronously. All works fine with the code below but when I have so many Images, our firewall will block my internet access because of so many threads concurrently requesting. Therefore I was looking for a solution how to restrict the count of concurrently running threads. I ended up with this thread telling me to use SemaphoreSlim but I am somehow not able to get the idea and how to implement this?

  • is that SemaphoreSlim wait or waitAsnyc (what is the difference anyway?) should be inside a foreach while adding tasks? Can I just create the task list with linq as I do in my code?
    • why is there used task.Run?
    • after which line is executed does the thread start? after task.run or task.whenall?

If that's not the best approach, please suggest a better one. I'm not sure if using MaxDegreeOfParallelism with parallel.foreach makes sense as well?

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

Async Function testUrl_async(ByVal myImage  As image) As Task(Of image)
   Dim myImageurl as string=myImage.imageurl
   myHttpResponse = Await myHttpClient.GetAsync(myImageurl)
    If myHttpResponse.IsSuccessStatusCode Then
        Return myImage
    Else
        Return Nothing
    End If
End Function

解决方案

our firewall will block my internet access because of so many threads concurrently requesting. Therefore I was looking for a solution how to restrict the count of concurrently running threads.

Pretty sure that the firewall is restricting your number of connections, and thus you want to restrict your number of connections (not threads).

is that SemaphoreSlim wait or waitAsnyc (what is the difference anyway?)

Wait is a synchronous wait - it blocks the calling thread. WaitAsync is an asynchronous wait - it frees the calling thread and resumes executing the current method when the semaphore is available.

should be inside a foreach while adding tasks? Can I just create the task list with linq as I do in my code?

You can do it either way: build up a list explicitly, or use LINQ.

why is there used task.Run?

That's an error in that answer. Task.Run is certainly not needed or desired here.

after which line is executed does the thread start? after task.run or task.whenall?

When you call Task.Run, that delegate is queued to the thread pool immediately. But as I said above, you don't want to use Task.Run (it also shouldn't be used in the original answer either).


So, something like this should suffice:

Private _mutex As New SemaphoreSlim(20)
Async Function testUrl_async(myImage As image) As Task(Of image)
    Await _mutex.WaitAsync()
    Try
        Dim myImageurl = myImage.imageurl
        Dim myHttpResponse = Await myHttpClient.GetAsync(myImageurl)
        Return If(myHttpResponse.IsSuccessStatusCode, myImage, Nothing)
    Finally
        _mutex.Release()
    End Try
End Function

这篇关于如何控制线程数,当我使用&QUOT; Task.WhenAll&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆