我有一个WCF应用程序接受启动作业的请求。每个工作需要在X分钟(例如5分钟)之后做一些事情,也可以随时同时提出工作要求。
这就是我想到的,
// WCF class
public class RequestManager
{
// WCF method
public void StartNewJob()
{
// start a new thread with timer for each job?
}
}
public class Job
{
public Job()
{
// do some initializations
// do something after x mins
// sleep or timer?
}
private void DoSomething()
{
// do some follow-ups
}
}
凭借我的方法,我担心会有太多线程无法为X分钟做任何事情。每秒精度也是一个要求(比如它在0:05:01开始工作,后续工作应该在0:10:01)。
最好的方法是什么?
答案 0 :(得分:1)
听起来你需要Timer类的服务:
// WCF class
public class RequestManager
{
// WCF method
public void StartNewJob()
{
Job myJob = new Job();
// Initialise myJob...
myJob.Start();
}
}
public class Job
{
private Timer myTimer = new Timer();
public Job()
{
myTimer.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
}
public void Start(int Miniutes)
{
myTimer.Interval = 60000 * Miniutes;
myTimer.Enabled = true;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// So something
}
}
以上代码假定:
它不是一个完整的例子,但希望它能给你一个想法 - Timer类将处理保持时间而不需要为每个作业激活一个线程。
答案 1 :(得分:1)
我建议您查看RegisterWaitForSingleObject函数:
var waitObject = new AutoResetEvent(false);
// Execute the callback on a new thread 10 seconds after this call
// and execute it only once
ThreadPool.RegisterWaitForSingleObject(
waitObject,
(state, timeout) => { Console.WriteLine("ok"); },
null,
TimeSpan.FromSeconds(10),
true);
// Execute the callback on a new thread 10 seconds after this call
// and continue executing it at 10 seconds intervals until the
// waitHandle is signaled.
ThreadPool.RegisterWaitForSingleObject(
waitObject,
(state, timeout) => { Console.WriteLine("ok"); },
null,
TimeSpan.FromSeconds(10),
false);
答案 2 :(得分:0)
您需要使用一些时序/调度框架,如Quartz.NET或创建自己的(轻量级)。
答案 3 :(得分:0)
对我来说,使用计时器似乎很好(也更容易实现)。
您可以在.NET中使用多个计时器类。请参阅以下文档(即使它有点老化,但似乎是一个好的开始):Comparing the Timer Classes in the .NET Framework Class Library
但是,您仍然可以通过Thread.Sleep()以及在线程唤醒和Job.DoSomethig()完成时获取时间戳来计算偏移量来实现此行为。
您可能需要仔细考虑以下事项:
执行Job.DoSomething()的线程之间的任何争论?
在以下场景中你应该非常小心:如果Job.DoSomething()有时需要超过句点(即它从0:05开始并在上面的例子中完成0:13)。这对您的应用程序意味着什么以及如何处理?
一个。总失败 - 在0:10中止当前(0:05)执行并启动0:10执行。
湾没什么大不了的(跳过0:10然后在0:15运行Job.DoSomething())。
℃。没什么大不了的,但需要在0:05任务完成后立即执行0:10执行(如果它持续超过5秒怎么办?)。
d。即使当前正在执行0:05执行,也需要启动0:10执行。
即其他什么?
对于您在上面选择的策略,您选择的实现(上面列出的任何计时器类或Thread.Sleep())是否都很容易支持您的策略?