我有一个Windows服务应用程序,它有许多不同的工作需要并行完成,并在三个不同的时间表上生成。但是我想确保在任何时候都没有N个任务正在运行。
这不是this question的副本,因为这是关于限制每秒启动的任务数,而不是同时运行的数量。也不是this的副本,因为我的任务是在不同的时间表上,所以不能同时排队。
以下是一些提供上下文的代码:
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
List<Task> ServiceTasks;
private List<Timer> ServiceTimers;
private static int N = 10;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
List<double> Times = new List<double>(){1000d,2000d,5000d};
for(int i = 0; i<3 ; i++)
{
var t = new Timer(Times[i]);
t.AutoReset = true;
ServiceTimers.Add(t);
}
ServiceTimers[0].Elapsed += Timer1Elapsed_DoSomething;
ServiceTimers[0].Start();
ServiceTimers[1].Elapsed += Timer2Elapsed_DoSomething;
ServiceTimers[1].Start();
ServiceTimers[2].Elapsed += Timer3Elapsed_DoSomething;
ServiceTimers[2].Start();
}
private void Timer1Elapsed_DoSomething(object sender, ElapsedEventArgs e)
{
ServiceTasks.Add(Task.Factory.StartNew(() => ServiceWork.DoTask1()));
}
private void Timer2Elapsed_DoSomething(object sender, ElapsedEventArgs e)
{
ServiceTasks.Add(Task.Factory.StartNew(() => ServiceWork.DoTask2()));
}
private void Timer3Elapsed_DoSomething(object sender, ElapsedEventArgs e)
{
ServiceTasks.Add(Task.Factory.StartNew(() => ServiceWork.DoTask3()));
}
}
}
如何修改此代码以确保在任何给定时间只运行N个任务?
答案 0 :(得分:1)
SemaphoreSlim
是一个允许你这样做的类。它是N个同时&#34;线程&#34;的锁定。
就像那样:
SemaphoreSlim s = ...;
async Task F() {
await s.WaitAsync();
DoWork();
s.Release();
}
如果你不介意每个线程等待1MB的堆栈使用,你也可以使用同步API。
此:
Task.Factory.StartNew(() => ServiceWork.DoTask3())
变为:
Task.Run(async () => {
await s.WaitAsync();
try {
ServiceWork.DoTask3();
} finally {
s.Release();
}
});
你可以开始无限数量的这些,他们会自我扼杀。
仍然需要任务列表,以便您可以通过等待所有任务完成并处理错误来干净地关闭服务。