如何在序列中运行C#任务

时间:2017-03-15 01:39:29

标签: c# multithreading

例如,我有10个任务。我想在同一时间运行x任务,如果任务完成,其他任务将被添加运行。 它喜欢Internet Download Manager中的队列

3 个答案:

答案 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。