public class JobRunner
{
internal Timer Timer;
internal readonly IEnumerable<YuartzJob> Jobs;
public void Start()
{
this.Timer = new Timer(5000);
this.Timer.Elapsed += Timer_Elapsed;
this.Timer.Start();
}
public void Stop()
{
this.Timer.Stop();
}
internal void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
foreach (var job in Jobs)
{
MyActivator.RunJob(job);
}
}
}
public class MyActivator
{
public static void RunJob(YuartzJob job)
{
var objectHandle = Activator.CreateInstance(job.AssemblyName, job.ClassName).Unwrap();
var currentJob = (IJob)objectHandle;
currentJob.Run();
}
}
我应该如何使用MyActivator.RunJob(作业):
答案 0 :(得分:3)
如果您的目标是.NET 4,最简单的方法是使用任务。任务使用ThreadPool中的线程执行方法。 .NET运行时(实际上是一个TaskScheduler)确保线程池不会被太多任务耗尽:
foreach (var job in Jobs)
{
Task.Factory.StartNew(()=>MyActivator.RunJob(job));
}
任务还允许轻松取消,异常处理和链接,这在使用ThreadPool或您自己的线程时是不可能的。
对于早期版本,您应首先考虑ThreadPool,并且只创建自己的线程,如果作业太长且运行时间很长,以至于它们可能会耗尽线程池:
foreach (var job in Jobs)
{
ThreadPool.QueueUserWorkItem(o=>MyActivator.RunJob(job));
}
后台工作程序在.NET 4+中被认为是过时的,并且仅适用于非常粗粒度的并行性。在您的情况下,您必须为每个作业创建一个单独的工作程序,订阅它的事件,运行它并在它之后进行清理。
答案 1 :(得分:2)
如果您想要有效地并行处理项目集合,我的第一选择就是为此目的而做的事情:Parallel.ForEach()
。
在内部,它使用Task
s,这意味着它将在ThreadPool
上运行。它还会尝试有效地使用Task
,所以如果你有一百万个项目的集合,它就不会创建一百万个Task
。
答案 2 :(得分:-1)
.NET Framework提供了四个计时器。其中两个是通用多线程定时器:
另外两个是特殊用途的单线程定时器:
因此,如果您希望以多线程方式/并行方式执行您的方法,那么您必须选择前两个方法。
详细了解此问题以及示例源代码here