这是我的要求:
需要应用程序或任务,它以24/7运行,具有可配置的时间间隔(在Delphi中)。
到目前为止我做了什么:
所以我决定去寻求Windows服务。
然后我在Delphi中创建了windows服务。
这个过程是 1.创建Windows服务Start():
procedure TDemo.ServiceStart(Sender: TService; var Started: Boolean);
begin
MyServiceThread := TMyThread.Create(False); //Call the thread
MyServiceThread.Resume;
end;
2。 Windows服务停止();
procedure TDemo.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
MyServiceThread.Terminate;
end;
线程的执行方法:
procedure TMyThread.Execute;
begin
MyTask();
end;
MyTask()具有一些功能,可能需要30秒到5分钟才能完成任务。
如果现在我启动服务,那么它调用execute方法并在其中调用MyTask()。然后我完成任务。它只会发生一次。因为根本没有循环。
然后我创建了Task调度程序并将Time interval设置为10 分钟并调用启动我的Windows服务的批处理文件 停止。
现在一切正常。每10分钟我的任务就完成了。
除了任务计划程序之外,还有什么其他可能性?内部服务本身可以吗?哪一个是最好的方法?
思考并找到一个解决方案:
1.在线程内创建Timer。但是Timer需要将时间设置为可配置的。可能是一天或一周等等..Timer支持的最长时间是多少?
可以用计时器吗?
还有其他办法吗?
请给我一些建议以寻求更好的解决方案。
答案 0 :(得分:1)
您可以使用创建计时器的方法。
现在,如果您可以根据系统时钟安排任务(例如从下午3点开始),那么您可以使用下一种方法。而不是更改计时器间隔,以便它在该特定时间点火,您将计时器保持1分钟的间隔。然后每次计时器触发时,只需检查系统时间是否大于计划时间。如果它是你需要进行的处理,否则你什么都不做。
所以现在你只需要一个有条理的列表,按排序顺序存储所有计划任务,这样你就不需要遍历整个列表并检查每个任务是否需要执行。
现在,如果使用系统closk不是一个选项,因为用户能够更改它实现自己的计数器,每次计时器触发时都会增加。所以现在你只需要将你的定时逻辑调整到你的计数器系统。
编辑:我建议的方法通常用于时间缠身的多人游戏浏览器游戏,其中每个任务都需要一定的时间。因此,服务器只会根据某个任务的命令何时发出以及该任务完成所需的时间来存储特定事件。答案 1 :(得分:0)
在Windows服务中安装计时器是一种选择。您还可以在开始新实例之前检查先前的实例是否已完成。但是,如果您必须不时地控制服务,这可能不是正确的选择。
多年来,我发现Autosys是最有用的调度代理。它带有客户端 - 服务器模型。因此,您可以从Autosys客户端工具控制作业。
TechScheduler是另一种选择,但现在它已经很老套了。
答案 2 :(得分:0)
首先,我不知道您的Delphi版本,但通常不推荐使用TThread.Resume
。您应该使用TThread.Start
。但即便如此,您也不需要启动该线程,因为它是使用False
参数创建的 - 即未挂起状态。
Execute()
只执行一次,因为你这样做了。
下面的代码是一个在一个时间间隔内“执行”的简单线程。
TMyThread = class(TThread)
private
fRefreshInterval: Integer; // milliseconds
fTerminateEvent: TEvent;
procedure SetRI(const Value: Integer);
protected
procedure Execute; override;
public
constructor Create(const aRefreshInterval: Integer = 600000);
destructor Destroy; override;
property RefreshInterval: Integer write SetRI;
end;
//// implementation
constructor TMyThread.Create;
begin
inherited Create(False);
fRefreshInterval := aRefreshInterval;
fTerminateEvent := TEvent.Create(nil, True, False, '');
Priority := tpLowest;
FreeOnTerminate := True;
end;
destructor TMyThread.Destroy;
begin
try
if not Terminated then
begin
Terminate;
fTerminateEvent.SetEvent;
end;
fTerminateEvent.Free;
except
//
end;
inherited;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
try
// your code here
except
// something bad happened
end;
fTerminateEvent.WaitFor(fRefreshInterval);
end;
end;
procedure TMyThread.SetRI(const Value: Integer);
begin
InterlockedExchange(fRefreshInterval, Value);
end;
如果您想每隔XX分钟执行一次任务,您必须记住执行任务所需的时间,并应该执行以下操作:
procedure TMyThread.Execute;
var
taskStartedAt: Cardinal;
taskDuration: Cardinal;
begin
while not Terminated do
begin
taskStartedAt := GetTickCount;
try
// your code here
except
// something bad happened
end;
taskDuration := GetTickCount - taskStartedAt;
if (fRefreshInterval > taskDuration) then
fTerminateEvent.WaitFor(fRefreshInterval - taskDuration);
end;
end;
无论如何,TTimer
和Task Scheduler
也是选项。
答案 3 :(得分:0)
我宁愿选择"计划任务"做法。这是Windows原生的方法 这样的任务,你只需要创建一个被调用的控制台应用程序 您在计划任务中定义的每个间隔。