【问题标题】:How to limit the number of active Tasks running via the Parallel Task Library?如何限制通过并行任务库运行的活动任务的数量?
【发布时间】:2013-07-16 18:42:05
【问题描述】:

我有一些 ConcurrentQueue 包含 Action ( System.Action )。 该队列中的每个动作都需要运行(需要使用invoke调用)。

当队列不为空时 => 需要调用该操作 => 但我想对将运行的并行任务的数量进行一些限制。 除此之外,可以随时将新操作添加到队列中。

怎么做?

(使用 .net 4.0)

我写了一些东西,但我不确定这是最好的方法

 SemaphoreSlim maxThread = new SemaphoreSlim(5);

 while( !actionQueue.IsEmpty )
        {
            maxThread.Wait();
            Task.Factory.StartNew( () =>
            {
                Action action;
                if( actionExecution.TryDequeue( out action) )
                {
                    action.Invoke();
                }
            },
            TaskCreationOptions.LongRunning ).ContinueWith( ( task ) => maxThread.Release() );
        }
    }

【问题讨论】:

  • 你能解释一下真正的问题吗?为什么你觉得有必要限制任务的数量?
  • 只是学术经验..我想学习。但我也想知道为什么我不需要做这个限制?
  • 没有必要限制任务的数量——我现在看到你说的是并发执行的任务,而不是队列中的总数;下面lazyberezovsky 的答案是适合这种情况的正确答案。
  • 看看 TPL 数据流,根据您的情况,它可以非常适合。 msdn.microsoft.com/en-us/library/hh228603.aspx

标签: c# task-parallel-library


【解决方案1】:

查看 MSDN 文章 How to: Create a Task Scheduler That Limits Concurrency。您可以使用其中的LimitedConcurrencyLevelTaskScheduler 实现来使您的代码如下所示:

var scheduler = new LimitedConcurrencyLevelTaskScheduler(5);
TaskFactory factory = new TaskFactory(scheduler);

while( !actionQueue.IsEmpty )
{
    factory.StartNew( () =>
    {
        Action action;
        if(actionExecution.TryDequeue(out action))                
            action.Invoke();

    }, TaskCreationOptions.LongRunning);
}

【讨论】:

  • 为什么这比 OP 建议使用 SemaphoreSlim 的解决方案更好?
【解决方案2】:

您需要指定 ParallelOptions

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 4;//value of your choice

if (Parallel.ForEach(PDFFiles, options, element =>
{
   //do work 
}

【讨论】:

    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 2014-05-31
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多