[英]Run tasks in parallel and some of them consecutively
我想并行运行方法 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
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");
}
}
您可以使用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
}
要描述输出,您可以尝试使用MethodA
、 MethodB1
和MethodB2
的以下实现
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);
}
}
这不适用于 VS2017 及更新版本,因为 VS2017 之前的控制台应用主干线不支持 async 关键字。 在旧版本中,您应该执行Task.WhenAll().Wait();
而不是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");
}
}
}
一种方法是委托回调机制类程序。 另一种可以是基于事件的Here is Used First 方法。 给定时间样本
这正是你想要的
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);
}
}
只需在 Parallel.Invoke 之后添加 B2。 Parallel.Invoke 在进入下一行之前等待完成。 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-use-parallel-invoke-to-execute-parallel-operations
public static void Main(string[] args)
{
Action[] actionsArray =
{
() => MethodA(),
() => MethodB1()
};
Parallel.Invoke(actionsArray);
MethodB2();
}
private static void MethodA()
{
Console.WriteLine("A");
Thread.Sleep(3000);
// more code is running here (30 min)
}
private static void MethodB1()
{
Console.WriteLine("B1");
Thread.Sleep(200);
// more code is running here (2 min)
}
private static void MethodB2()
{
Console.WriteLine("B2");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.