例如,我有10个任务。我想在同一时间运行x任务,如果任务完成,其他任务将被添加运行。 它喜欢Internet Download Manager中的队列
答案 0 :(得分:1)
正如Cory Nelson所指出的那样,Microsoft.Tpl.Dataflow可以满足您的需求。首先添加nuget包,然后使用您想要的设置实例化ActionBlock
:
var actionBlock = new ActionBlock<string>(new Action<string>(Execute), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });
在这里,它将为您排队的每个字符串调用Execute
方法(有效负载可能是其他内容,此处我假设字符串是您要下载的文件的URL)。 ActionBlock
将确保并发运行的线程不超过10个。
使用Post
方法排除某些工作:
actionBlock.Post("http://.../");
这是一个简单的概念证明:
class Program
{
private static int ConcurrentActions = 0;
public static void Main()
{
var actionBlock = new ActionBlock<string>(new Action<string>(Execute), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 });
for (int i = 0; i < 20; i++)
{
actionBlock.Post(i.ToString());
}
actionBlock.Complete();
while (!actionBlock.Completion.IsCompleted)
{
Console.WriteLine("Concurrent actions: {0}", ConcurrentActions);
Thread.Sleep(200);
}
Console.WriteLine("Done");
Console.ReadLine();
}
private static void Execute(string url)
{
Interlocked.Increment(ref ConcurrentActions);
Thread.Sleep(1000); // Workload
Interlocked.Decrement(ref ConcurrentActions);
}
}
答案 1 :(得分:0)
你想链接任务吗?正如第一个任务完成第二个任务开始一样?
您可以使用ContinueWith()
参考msdn:https://msdn.microsoft.com/en-us/library/dd537612(v=vs.110).aspx
答案 2 :(得分:0)
例如,我有10个任务。我想在同一时间运行x任务
这是一种并发限制方案。
如果通过&#34; task&#34;,你的意思是你想要运行的一些CPU绑定代码(也就是说,每个&#34;任务&#34; 同步在性质上),然后适当的工具是在DegreeOfParallelism
或PLINQ调用上设置Parallel
,如:
data.AsParallel().WithDegreeOfParallelism(x).Select(d => ...).ToList();
如果通过&#34;任务&#34;,则表示实际的Task
(也就是说,每个&#34;任务&#34; 异步),那么适当的工具是SemaphoreSlim
使用Task.WhenAll
,例如:
var throttler = new SemaphoreSlim(x);
var tasks = data.Select(async d =>
{
await throttler.WaitAsync();
try { ... }
finally { throttler.Release(); }
}).ToList();
await Task.WhenAll(tasks);
或者,您可以use TPL Dataflow,它可以使用同步或异步&#34;任务&#34; s。