System.Threading.Tasks - 限制并发任务的数量

Jam*_*mes 43 .net asp.net multithreading task

我刚刚开始研究.Net 4.0中新的"System.Threading.Tasks"的好处,并且想知道是否有任何构建支持限制一次运行的并发任务的数量,或者是否应该手动处理.

EG:如果我需要调用100次计算方法,有没有办法设置100个任务,但只有5个同时执行?答案可能只是创建5个任务,调用Task.WaitAny,并在前一个任务完成时创建一个新任务.我只是想确保如果有更好的方法,我不会错过任何一招.

基本上,有没有内置的方法来做到这一点:

Dim taskArray() = {New Task(Function() DoComputation1()),
                   New Task(Function() DoComputation2()),
                   ...
                   New Task(Function() DoComputation100())}

Dim maxConcurrentThreads As Integer = 5
RunAllTasks(taskArray, maxConcurrentThreads)
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

Jam*_*mes 45

我知道这已经快一年了,但我找到了一种更容易实现的方法,所以我想我会分享:

Dim actionsArray() As Action = 
     new Action(){
         New Action(Sub() DoComputation1()),
         New Action(Sub() DoComputation2()),
         ...
         New Action(Sub() DoComputation100())
      }

System.Threading.Tasks.Parallel.Invoke(New Tasks.ParallelOptions() With {.MaxDegreeOfParallelism = 5}, actionsArray)
Run Code Online (Sandbox Code Playgroud)

瞧!


Arr*_*der 28

我知道这是一个旧线程,但我只是想分享我对这个问题的解决方案:使用信号量.

(这是在C#中)

private void RunAllActions(IEnumerable<Action> actions, int maxConcurrency)
{
    using(SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency))
    {
        foreach(Action action in actions)
        {
            Task.Factory.StartNew(() =>
            {
                concurrencySemaphore.Wait();
                try
                {
                    action();
                }
                finally
                {
                    concurrencySemaphore.Release();
                }
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会产生很多任务吗?concurrencySemaphore.Wait()在新任务lambda块中. (5认同)

per*_*ent 7

解决方案可能是在这里查看 Microsoft的预制代码.

描述如下:"提供一个任务调度程序,确保在ThreadPool之上运行时获得最大并发级别.",并且就我能够测试它而言似乎可以做到这一点,就像以下一样: ParallelOptions中的MaxDegreeOfParallelism属性.


Nig*_*ist 6

C#相当于詹姆斯提供的样本

Action[] actionsArray = new Action[] {
new Action(() => DoComputation1()),
new Action(() => DoComputation2()),
    //...
new Action(() => DoComputation100())
  };

   System.Threading.Tasks.Parallel.Invoke(new Tasks.ParallelOptions {MaxDegreeOfParallelism =  5 }, actionsArray)
Run Code Online (Sandbox Code Playgroud)