不同时间的并行任务执行
Parallel task execution at different time
我有一个控制台应用程序,它可以并行执行几个任务。就我而言,重要的部分是我希望任务同时完成。我知道每项任务需要多长时间。因此,我们的想法是以某种方式延迟 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 . . .
我想最明显的解决方案是在循环中区分哪个服务是 z 并在调用 z.DoWork() 之前添加自定义 Thread.Sleep,但我正在寻找更智能的解决方案。
感谢您的帮助!所以这就是我想要实现的。所有服务同时完成它们的工作。这是正确的做法吗?
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)代表一些耗时操作。
我有一个控制台应用程序,它可以并行执行几个任务。就我而言,重要的部分是我希望任务同时完成。我知道每项任务需要多长时间。因此,我们的想法是以某种方式延迟 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 . . .
我想最明显的解决方案是在循环中区分哪个服务是 z 并在调用 z.DoWork() 之前添加自定义 Thread.Sleep,但我正在寻找更智能的解决方案。
感谢您的帮助!所以这就是我想要实现的。所有服务同时完成它们的工作。这是正确的做法吗?
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)代表一些耗时操作。