并行运行任务,并连续执行其中一些任务

时间:2017-10-05 05:49:53

标签: c# task task-parallel-library

我想并行运行方法A和方法B1。这很有效。但是如何在B1完成后运行方法B2?

    class Program
    {
        static void Main(string[] args)
        {
            //var firstTask = Task.Factory.StartNew(() => MethodB1());
            //var secondTask = firstTask.ContinueWith( (antecedent) => MethodB2());

            Action[] actionsArray =
            {
                () => MethodA(),
                () => MethodB1(),
            };

            Parallel.Invoke(actionsArray);
        }

        private static void MethodA()
        {
            Console.WriteLine("A");
            // more code is running here (30 min)
        }

        private static void MethodB1()
        {
            Console.WriteLine("B1");
            // more code is running here (2 min)
        }

        private static void MethodB2()
        {
            Console.WriteLine("B2");
        }
    }

编辑: 我希望下面的例子能够阻止这种混乱。 ;)

A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> A
B1 -> B1 -> B1 -> B1 -> B1 -> B2 -> B2 -> B2

5 个答案:

答案 0 :(得分:1)

C#是一种很好的语言,有很多方法可以做到这一点,因为评论建议另一种方法就是这样:

static void Main()
{
    var t = MethodA();
    MethodB1().ContinueWith((r) =>
    MethodB2()).Wait();
    t.Wait();
}

private static async Task MethodA()
{
    await Task.Run(() =>
    {
        for (int i = 0; i < 40; i++)
        {
            Thread.Sleep(100);
            Console.WriteLine("A");
        }
    });
}

private static async Task MethodB1()
{
    await Task.Run(() =>
    {
        for (int i = 0; i < 10; i++)
        {
            Thread.Sleep(100);
            Console.WriteLine("B1");
        }
    });
}

private static void MethodB2()
{
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(100);
        Console.WriteLine("B2");
    }
}

答案 1 :(得分:1)

您可以使用ContinueWith轻松实现此目的。这是代码

 public static void Main(string[] args)
 {
     var t1 = Task.Factory.StartNew(MethodA);           
     var t2 = Task.Factory.StartNew(MethodB1).ContinueWith(task => MethodB2());   
     Task.WaitAll(t1, t2); // If you want to wait here for finishing the above tasks                                           
 }

要描述输出,您可以尝试使用MethodAMethodB1MethodB2

的以下实现
private static void MethodA()
{
    for (int i = 0; i < 100; i++)
    {
        Console.Write("A ");
        Thread.Sleep(100);
    }  
}

private static void MethodB1()
{

    for (int i = 0; i < 100; i++)
    {
        Console.Write("B1 ");
        Thread.Sleep(100);
    }
}

private static void MethodB2()
{
    for (int i = 0; i < 100; i++)
    {
        Console.Write("B2 ");
        Thread.Sleep(100);
    }
}

答案 2 :(得分:0)

这不适用于VS2017及更新版本,因为VS2017之前的控制台应用主电源不支持async关键字。在旧版本上,您应该await Task.WhenAll()

而不是Task.WhenAll().Wait();
namespace ConsoleApp3
{
    class Program
    {
        static async void Main(string[] args)
        {
            var taskA = Task.Run(() => MethodA()); //Start runnning taskA
            var taskB1AndB2 = Task.Run(() => MethodB1()).ContinueWith(async (taskb1) => { await taskb1; await Task.Run(()=>MethodB2()); }).Unwrap(); //When taskB1 is complete, continue with taskB2
            await Task.WhenAll(taskA, taskB1AndB2); //wait until all 3 tasks are completed
        }

        private static void MethodA()
        {
            Console.WriteLine("A");
            // more code is running here (30 min)
        }

        private static void MethodB1()
        {
            Console.WriteLine("B1");
            // more code is running here (2 min)
        }

        private static void MethodB2()
        {
            Console.WriteLine("B2");
        }
    }
}

答案 3 :(得分:0)

一种方法是委托CallBack机制类程序。另一个可以基于事件这是第一种方法。给出时间样本

这正是您想要的

class Program
{

    static System.Collections.Concurrent.ConcurrentQueue<Action> leftOvers = new System.Collections.Concurrent.ConcurrentQueue<Action>();
    static void Main(string[] args)
    {


        for (int i = 0; i < 100; i++)
        {
            Task.WaitAll(MethodA(), MethodB1(MethodB2));
        }

        Action callBack = null;
        while (leftOvers.TryDequeue(out callBack))
        {
            callBack();
        }
        Console.ReadLine();
    }

    private static void QueueMethods(Action method)
    {
        leftOvers.Enqueue(method);
    }

    private async static Task MethodA()
    {
        await Task.Run(() => Console.WriteLine("A  at" +  DateTime.Now.TimeOfDay ));

    }


    private async static Task MethodB1(Action callBack)
    {
        await Task.Run(() => Console.WriteLine("B1 at" + DateTime.Now.TimeOfDay));
        leftOvers.Enqueue(callBack);

    }

    private  static void MethodB2()
    {
        Console.WriteLine("B2 at" + DateTime.Now.TimeOfDay);

    }
}

答案 4 :(得分:-1)

在Parallel.Invoke之后添加B2。 Parallel.Invoke在进入下一行之前等待完成。 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-use-parallel-invoke-to-execute-parallel-operations

ionic start myApp sidemenu