如何在C#中创建具有多个计时器的调度程序服务 [英] How do I create scheduler service having multiple timer in C#

查看:68
本文介绍了如何在C#中创建具有多个计时器的调度程序服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个Windows C#服务,该服务在通过LAN连接10到15个目标设备的服务器上运行。所以这就是我在服务中所做的事情我正在从csv文件中读取数据,格式如下:



I am trying to create a windows C# service which runs on server connected with 10 to 15 target devices via LAN. So here is the what I am doing in service i am reading the data from csv file which is in following format:

TargetComputername1,Date1,Time1,Password1
TargetComputername2,Date2,Time2,Password2
TargetComputername3,Date3,Time3,Password3
.
.
TargetComputernameN,DateN,TimeN,PasswordN







我必须在服务中运行vbs但是在指定的日期和在目标名称和密码作为参数的csv中的时间。



因此对于N设备我认为我必须创建N个不同的计时器实例并传递参数我应该怎么做?



请提前帮助感谢...



我的尝试:






I have to run a vbs inside service but on the specified date & time in csv with Targetname and password as parameter.

So for N device i think i have to create N different instance of timer and pass the parameters how should i do that?

Pleas help thanks in advance...

What I have tried:

using (var parser = new TextFieldParser(AppPath + "\\iPXEScheduler.csv"))
{
	parser.TextFieldType = FieldType.Delimited;
	parser.SetDelimiters(",");

	string[] line;
	int count = 1;
	while (!parser.EndOfData)
	{
		count++;
		line = parser.ReadFields();
		if (bStringContains(line[0], sDeviceNameGet("StoreID"), StringComparison.OrdinalIgnoreCase))
		{
			if (validate(line, count))
			{
				SetupTimer();
			}
		}
	}
}

//validate function
private bool validate(string[] line, int count)
{
	/*for reference
	line[0]=device name
	line[1]=Date
	line[2]=time
	line[3]=countdown
	line[4]=Password
	*/

	//Local variables
	bool bISValidate = true;
	Double dLOCCountDown = 1.0;
	string sLOCTime;
	DateTime dtScheduledDateTime = DateTime.Now.AddYears(1000); //Any imaginary date just to sufice try catch;
	string[] DateTimeformat = { "MM/dd/yyyy HH:mm", "M/d/yyyy H:mm", "MM/d/yyyy H:mm", "M/dd/yyyy H:mm", "M/d/yyyy HH:mm", "MM/d/yyyy HH:mm", "M/dd/yyyy HH:mm" };

	if (line.Length != 5)
	{
		WriteLog("There are more or less then 5 parameter specified in csv at line : " + count);
		bISValidate = false;
		goto Error;
	}
	if (line[0]=="" && line[1]=="" && line[2]=="" && line[3]==""&&line[4]=="")
	{
		WriteLog("One of the parameter found blank at : " + count);
		bISValidate = false;
		goto Error;
	}
	if (line[0].Length != 12)
	{
		WriteLog("Please check the device name at line : " + count);
		bISValidate = false;
		goto Error;
	}

	//In case POS close is specified instead of Time.
	if (bStringContains(line[2], "CLOSE", StringComparison.OrdinalIgnoreCase))
	{
		sLOCTime = "00:00";
	}
	else
	{
		sLOCTime = line[2];
	}

	//Validating date and time
	try
	{
		dtScheduledDateTime = DateTime.ParseExact(line[1] + " " + line[2], DateTimeformat, null, System.Globalization.DateTimeStyles.None);
	}
	catch(Exception ex)
	{
		WriteLog("Error parsing date and time : " + ex.Message);
		WriteLog("Correct date format is : MM/dd/yyyy and time is : HH:mm (24 hours)");
		bISValidate = false;
		goto Error;
	}

	//Parse the count down value
	try
	{
		dLOCCountDown = Double.Parse(line[3]);
		if (dLOCCountDown < 1.0 && dLOCCountDown > 99.0)
		{
			WriteLog("Countdown can not be less then 1 and greater then 99 " + dLOCCountDown);
			bISValidate = false;
			goto Error;
		}

	}
	catch(Exception ex)
	{
		WriteLog("Error parsing CoutDown : " + ex.Message);
	}

	//Validate password only for digits
	if (!IsDigitsOnly(line[4]))
	{
		WriteLog("Password seems to contain character other then digit which is not allowed at line : " + count);
		bISValidate = false;
		goto Error;
	}

	Error:
	if (bISValidate == false)
	{
		return false;
	}
	else
	{
		DateTime dtGLOScheduleDateTime = dtScheduledDateTime;
		Double dGLOCountDown = dLOCCountDown;
		string sGLOPassword = DecryptPassword(line[4]); //line[4] contains password;
		string sGLODevice = line[0]; //contains Device name;
		return true;
	}
}


//timer function:

private void SetupTimer()
{
	Timer Countdown = new Timer();
	Countdown.AutoReset = false;
	WriteLog(dtGLOScheduleDateTime.ToString());
	Countdown.Interval = (dtGLOScheduleDateTime.Subtract(DateTime.Now).TotalSeconds * 1000) - (dGLOCountDown * 24 * 60 * 60 * 1000);
	Countdown.Elapsed += (sender, e) => Countdown_Elapsed(sender, e, sGLOPassword);
	Countdown.Start();

}

private void Countdown_Elapsed(object sender, ElapsedEventArgs e, string sGLOPassword)
{
	WriteLog(DateTime.Now.ToString() + " : " + sGLOPassword);

}





但我如何传递参数



But how do i pass the parameter as well

推荐答案

建议:更改代码以便只使用1个计时器。
Advice: Change your code in order to use only 1 timer.


您不会为文本文件中的每个项目使用计时器。你使用一个计时器,每分钟滴答一次。然后,根据每个项目列出的时间检查当前时间。如果当前的小时和分钟是相同的,启动任何代码正在为单个机器执行工作并将该机器的参数传递给它。
You're not going to use a timer for each item in the text file. You use a single timer, that "ticks" once a minute. You then check the current time against the time listed for each item. If the current hour and minute is the same, kick off whatever code is doing the work for a single machine and pass the parameters for that machine to it.


我不确定您是否需要这样的服务,但我们稍后会讨论。



首先,让我解释一下为什么不需要多个计时器。而且,您也不需要定期点火计时器。首先,让我们假设你的日程安排不是太紧,所以你有足够的时间来重置每个事件的计时器。



这就是你做的。比方说,你有10-15个具有不同拦截时间表的设备,每个时间表都很复杂。您必须创建所有设备的所有联合计划的队列。应按所需事件的时间排序。 queue元素应该引用适当的时间和设备。难怪,所有的设备都会出现在这个统一的时间表中,混合在一起,可能是不规则的顺序。不用担心。



您的事件处理程序应该是一个事件的处理程序。在初始化时,您初始化计时器并设置其计时时间,获取当前实时和队列的第一个条目。处理程序获取最高队列条目,根据队列元素中的信息执行其工作,然后将计时器重置为下一个元素。已经使用过的元素已从队列中删除。



现在,答案的第二部分,另一种选择......为什么要创建这项服务?为什么不使用已有的服务?您可以使用名为 Windows任务计划程序的Windows服务,请参阅:

http ://en.wikipedia.org/wiki/Task_Scheduler [ ^ ],

http://msdn.microsoft.com/en -us / library / aa383614.aspx [ ^ ],

http ://msdn.microsoft.com/en-us/library/aa384006%28v=VS.85%29.aspx [ ^ ]。



见上面的最后一个链接,用于使用Windows任务计划程序。您可以使用任务计划程序托管包装程序在程序中使用其API,请参阅 http://taskscheduler.codeplex.com/ [ ^ ]。



但是,如果可以更简单。
您可以使用Windows实用程序AT.EXE或SchTasks.EXE使用Windows任务计划程序,请参阅:

http://en.wikipedia.org/wiki/At_(Windows) [ ^ ],

http://technet.microsoft.com/en-us/library/bb490866.aspx [ ^ ],

http://en.wikipedia.org/wiki/Schtasks [ ^ ],

http://msdn.microsoft.com/en-us/library/windows/desktop/bb736357%28v=vs.85%29.aspx [ ^ ]。



-SA
I'm not sure you need such service at all, but we'll discuss it later.

First of all, let me explain why don't need multiple timers. Moreover, you also don't a need periodically firing timer. First of all, let's assume your schedules are not too tight, so you have enough time to reset a timer on each event.

Here is what you do. Let's say, you have 10-15 devices with different intercepting schedules, each schedule can be complicated. You have to create a queue of all united schedules of all devices. It should be ordered by time of required event. The queue element should reference appropriate time and device. No wonder, all the devices will appear in this united schedule, mixed in some, possibly irregular order. Not to worry.

You event handler should be the handler of one single event. At initialization, you initialize your timer and setup its tick time, taking current real time and first entry of the queue. The handler takes the top queue entry, performs its work according the the information in the queue element, and then reset timer to a next element. Already used element is removed from the queue.

Now, the second part of the answer, another alternative… Why creating this service at all? Why not using already available service? You can use the Windows service called Windows Task Scheduler, please see:
http://en.wikipedia.org/wiki/Task_Scheduler[^],
http://msdn.microsoft.com/en-us/library/aa383614.aspx[^],
http://msdn.microsoft.com/en-us/library/aa384006%28v=VS.85%29.aspx[^].

See the last link above for use of the Windows Task Scheduler. You can use its API in your program using Task Scheduler Managed Wrapper, see http://taskscheduler.codeplex.com/[^].

But if can be even simpler.
You can use Windows Task Scheduler using Windows utilities AT.EXE or SchTasks.EXE, see:
http://en.wikipedia.org/wiki/At_(Windows)[^],
http://technet.microsoft.com/en-us/library/bb490866.aspx[^],
http://en.wikipedia.org/wiki/Schtasks[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/bb736357%28v=vs.85%29.aspx[^].

—SA


这篇关于如何在C#中创建具有多个计时器的调度程序服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆