我有控制台应用程序并行执行几项任务。在我的情况下,重要的是我希望任务同时完成。我知道每项任务要花多长时间。因此,想法是以某种方式延迟Parallel.ForEach中的每个任务,每个任务具有自定义时间延迟,因此它们都在同一时间完成,并且最终所有任务将与花费大部分时间的任务同时完成。
示例:
interface IService
{
void DoWork();
}
class Program
{
static void Main(string[] args)
{
var services = new List<IService>();
services.Add(new ServiceA());//Takes 500ms to DoWork()
services.Add(new ServiceB());//Takes 1000ms to DoWork()
services.Add(new ServiceC());//Takes 5000ms to DoWork()
Parallel.ForEach(services, z =>
{
Stopwatch sw = new Stopwatch();
sw.Start();
z.DoWork();
Console.WriteLine($"Ready for {sw.Elapsed}");
});
}
}
输出:
Ready for 00:00:00.5006837
Ready for 00:00:01.0002284
Ready for 00:00:05.0010202
Press any key to continue . . .
如何修改代码,使输出如下:
Ready for 00:00:05.5006837
Ready for 00:00:05.0002284
Ready for 00:00:05.0010202
Press any key to continue . . .
我想最明显的解决方案是在循环中区分哪个Service是z并在调用z.DoWork()之前添加自定义Thread.Sleep,但我正在寻找更智能的解决方案。
答案 0 :(得分:1)
感谢您的帮助!所以这就是我想要实现的目标。所有服务同时完成他们的工作。这是正确的做法吗?
class Program
{
static void Main(string[] args)
{
ServiceA a = new ServiceA();
ServiceB b = new ServiceB();
ServiceC c = new ServiceC();
int maxDelay = 3000;
var sw = new Stopwatch();
sw.Start();
Task taskA = Task.Delay(maxDelay - a.ResponseTime).ContinueWith(x =>
{
a.DoWork();
Console.WriteLine($"taskA ready for {sw.Elapsed}");
});
Task taskB = Task.Delay(maxDelay - b.ResponseTime).ContinueWith(x =>
{
b.DoWork();
Console.WriteLine($"taskB ready for {sw.Elapsed}");
});
Task taskC = Task.Delay(maxDelay - c.ResponseTime).ContinueWith(x =>
{
c.DoWork();
Console.WriteLine($"taskC ready for {sw.Elapsed}");
});
taskA.Wait();
taskB.Wait();
taskC.Wait();
Console.WriteLine(sw.Elapsed);
}
}
class ServiceA
{
public int ResponseTime { get => 500; }
public void DoWork() => Thread.Sleep(500);
}
class ServiceB
{
public int ResponseTime { get => 1000; }
public void DoWork() => Thread.Sleep(1000);
}
class ServiceC
{
public int ResponseTime { get => 3000; }
public void DoWork() => Thread.Sleep(3000);
}
输出:
taskA ready for 00:00:03.0084344
taskC ready for 00:00:03.0102184
taskB ready for 00:00:03.0102588
* Thread.Sleep(x)表示一些耗时的操作。