C#可靠延迟/安排执行最佳实践 [英] c# reliable delayed/scheduled execution best practice
问题描述
我工作的项目需要一些执行在一定的时间内完成。我不知道什么是处理这种情况的最好办法。该方法必须能够生存服务器重启/维修。 。和方法的调用必须以编程
The project I am working on requires some executions to be done at a certain time. I am not sure what would be the best way to deal with this situation. The method must be able to survive server restart/maintenance. And method calls must be programmatically.
我正在考虑走这条路:
我可以有一个表数据库(甚至一个消息队列)呼吁TaskTable这可能会对的TaskID(PK),TASKNAME(VARCHAR),TaskStatus(枚举成功,失败,计划)和TimeOfExecution。但我需要一个Windows服务,定期轮询未执行任何任务的数据库。我现在面临的问题是:我应该使用什么作为TASKNAME保存到数据库中?班级名称?类和方法名的ToString?而且我怎么能字符串转换回编程方式调用方法调用(我不希望有一个巨大的switch语句)?一个typtical任务看起来像下面。所以,我定义为能够获得任务名称SendIncompleteNotification和类的名称将它保存到数据库中并retrival调用编程
I could have a table in database (or even a message queue) called TaskTable which could have TaskID(PK), TaskName(varchar), TaskStatus(enum success,failed, scheduled) and TimeOfExecution. But I need a windows service that periodically polls the database for any unexecuted tasks. Problem I am facing is that: What do I use as the TaskName to save into database? Class name? class and method name ToString? And how can I convert the string back and programmatically invoke the method calls (I don’t want to have a giant switch statement)? A typtical task would look like below. So I ned to be able to get the name of the task "SendIncompleteNotification" and class name save it into database and on retrival invoke programatically
public static Task<string> SendIncompleteNotification
{
get
{
return new Task<string>
(
a => Console.WriteLine("Sample Task")
, "This is a sample task which does nothing."
);
}
}
现在的问题是我有问题,保存方法。/属性名称progrmatically
The problem now is I am having problem saving the method/property name progrmatically.
var type = ApplicationTask.SendIncompleteNotification.GetType();
//type.Name shows "Task`1" rather than SendIncompleteNotification
有什么处理这种情况的更好的方法? !谢谢
Is there any better ways of dealing with this situation? Thanks!
更新:
对不起我头晕目眩。我现在意识到我做错了什么是有另一种方法/属性返回我的任务。我应该做的是从我工作一个新的类inhrite。在那里我可以轻松地获得类名和字符串保存到数据库,后来retireve背部和调用。
Updated: Sorry my head was spinning. I now realized what I did wrong was to have another method/property to return my Task. What I should have done was to have a new class inhrite from my Task. And there i can easily get the class name and save the string into db and later retireve back and invoke.
推荐答案
是数据库要求?
如果没有,何谈一个Windows计划任务(他们有一种倾向只是工作),其中要求到一般的控制台应用程序。到控制台应用程序的参数可以是:
If not, what about a Windows Scheduled Task (they have a tendancy to "just work") which calls into a general console app. The arguments to the console app could be:
- 包含任务DLL执行
- 的实现你定义一个接口的类的名称
- 其他参数
这样,您就可以把所有任务到一个部件或多个。另外,您可以创建一个属性,该属性适用于您的任务给他们一个友好名称,并使用反射在装配找到类具有匹配属性。
This way you can put all of your tasks into one assembly, or multiple. Alternatively you could create an attribute, apply that attribute to your tasks to give them a "friendly name", and use reflection over the assembly to find classes with the matching attribute.
编辑:例如:
interface ITask
{
void Execute(ExcecutionContext context);
}
[TaskName("Send Emails")
class SendEmailsTask : ITask
{
public void Execute(ExcecutionContext context)
{
// Send emails. ExecutionContext might contain a dictionary of
// key/value pairs for additional arguments needed for your task.
}
}
class TaskExecuter
{
public void ExecuteTask(string name)
{
// "name" comes from the database entry
var types = Assembly.GetExecutingAssembly().GetTypes();
foreach (var type in types)
{
// Check type.GetCustomAttributes for the TaskAttribute, then check the name
}
}
}
编辑2:这是在回答您的代码示例
Edit 2: This is in answer to your code sample.
class YourClass
{
public static Task<string> SendIncompleteNotification
{
get {
return new Task<string>(
s => Console.WriteLine("Executing task... arguments: {0}", s),
"My task");
}
}
}
interface ITask
{
void Execute(object o);
}
class Task<T> : ITask
{
public Task(Action<T> action, string name)
{
Action = action;
}
public string Name { get; set; }
public Action<T> Action { get; set; }
void ITask.Execute(object o)
{
Action((T)o);
}
}
class Program
{
static void Main(string[] args)
{
// Assume that this is what is stored in the database
var typeName = typeof (YourClass).FullName;
var propertyName = "SendIncompleteNotification";
var arguments = "some arguments";
// Execute the task
var type = Type.GetType(typeName);
var property = type.GetProperty(propertyName);
var task = (ITask)property.GetValue(null, null);
task.Execute(arguments);
Console.ReadKey();
}
}
这篇关于C#可靠延迟/安排执行最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!