如何通过并行任务库限制正在运行的活动任务数量?

8
我有一些包含Action (System.Action)的ConcurrentQueue。这个队列中的每个操作都需要运行(需要使用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() );
        }
    }

2
你能解释一下实际问题吗?为什么你感觉需要限制任务数量? - J...
只是学术经验...我想学习。但我也想知道为什么我不需要设置这个限制? - Yanshof
1
没有必要限制任务的数量 - 我现在明白你说的是并发执行任务而不是队列中的总数;lazyberezovsky下面的答案对于这种情况是正确的。 - J...
2
看看TPL数据流,根据您的情况,它可能非常合适。 http://msdn.microsoft.com/en-us/library/hh228603.aspx - Polity
2个回答

14

请查看MSDN文章"如何创建一个限制并发的任务计划程序"。您可以使用其中的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更好? - BornToCode

-1

你需要指定ParallelOptions

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接