C#可靠延迟/安排执行最佳实践 [英] c# reliable delayed/scheduled execution best practice

查看:219
本文介绍了C#可靠延迟/安排执行最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的项目需要一些执行在一定的时间内完成。我不知道什么是处理这种情况的最好办法。该方法必须能够生存服务器重启/维修。 。和方法的调用必须以编程

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屋!

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