正在创建任务计划程序

本文关键字:计划 程序 任务 创建 | 更新日期: 2023-09-27 18:24:06

在我正在创建的应用程序中,我希望有一个调度器来保存传入作业的数据以及执行这些作业的剩余时间,所以我创建了一个非常天真的实现,我认为它远远不是应该的。

实施

接口

public interface IQueue
{
    string Name { get; set; }
    int Priority { get; set; }
}

类别

public class TaskScheduler : Queue, IQueue
{
    public string Name { get; set; }
    public int Priority { get; set; }
    public TaskScheduler(string name, int priority)
    {
        Name = name;
        Priority = priority;
    }
    public void Add(string work, TimeSpan execution)
    {
        Enqueue(new Job {Work = work, Execution = execution});
    }
    public Job Get()
    {
        return (Job) Dequeue();
    }
}
public class Job
{
    public string Work { get; set; }
    public TimeSpan Execution { get; set; }
    public override string ToString()
    {
        return string.Format("{0} will be excuted in {1}", Work, Execution);
    }
}

用法

    var schedulerss = new List<TaskScheduler>
                         {
                             new TaskScheduler("Meetings", 2), 
                             new TaskScheduler("Jobs", 1)
                         };
    schedulerss = schedulerss.OrderBy(element => element.Priority).ToList(); //ORDER THE schedulers according to the Priority
    schedulerss.Find(schedulers => schedulers.Name == "Meetings").Add("Meet Barack Obama", new TimeSpan(1, 0, 0, 15));
    schedulerss.Find(schedulers => schedulers.Name == "Jobs").Add("Make a cheese sandwich :D", new TimeSpan(0, 2, 0, 15));
    var meetingschedulers = schedulerss.Find(schedulers => schedulers.Name == "Meetings");
    if (null != meetingschedulers)
    {
        foreach (var job in meetingschedulers)
        {
            Console.WriteLine(job);
        }
    }
    Console.Read();

问题

这段代码能很好地工作吗?还是我错过了所有的东西,有更好的方法来做这件事?

请求

请给我一个非常详细的答案,关于我提供的代码的缺点是什么,以及我如何创建一个更好的可重用代码(只针对其他可能觉得这个主题有用的人)。

正在创建任务计划程序

正如您从使用中看到的那样,在调度器中包含调度器的名称会使代码变得有点古怪。。。调度程序真的需要知道自己的名字吗?我会用Dictionary<string, TaskScheduler>()代替,并把他们的名字写在那里。。

此外,您的队列总是返回一个Job,因此您应该使用一个通用队列Queue<Job>

我做了一些修改

实施

接口

public interface IQueue
{
    int Priority { get; set; }
}

类别

public class TaskScheduler : Queue<Job>, IQueue
{
    public int Priority { get; set; }
    public TaskScheduler(int priority)
    {
        Priority = priority;
    }
    public void Add(string work, TimeSpan execution)
    {
        Enqueue(new Job { Work = work, Execution = execution });
    }
    public Job Get()
    {
        return Dequeue();
    }
}
public class Job
{
    public string Work { get; set; }
    public TimeSpan Execution { get; set; }
    public override string ToString()
    {
        return string.Format("{0} will be excuted in {1}", Work, Execution);
    }
}

用法

        var schedulers = new Dictionary<string, TaskScheduler>();
        schedulers.Add("Meetings", new TaskScheduler(2));
        schedulers.Add("Jobs", new TaskScheduler(1));
        schedulers["Meetings"].Add("Meet Barack Obama", new TimeSpan(1, 0, 0, 15));
        schedulers["Jobs"].Add("Make a cheese sandwich :D", new TimeSpan(0, 2, 0, 15));
        if (schedulers.ContainsKey("Meetings"))
        {
            foreach (var job in schedulers["Meetings"])
            {
                Console.WriteLine(job);
            }
        }

其他建议

由于您确实使用多个调度器,我建议您制作某种schedulerController,它将为您处理优先级排序,以及您可能想要添加的其他内容。

根据请求编辑示例

我不知道你到底想用你的调度器做什么,但我的意思是这样的,一个实用程序类:

public class TaskSchedulerController
{
    private Dictionary<string, TaskScheduler> _scedulers;
    public TaskSchedulerController()
    {
        _scedulers = new Dictionary<string, TaskScheduler>();
    }
    public void Add(string name, int priority)
    {
        _scedulers.Add(name, new TaskScheduler(priority));
    }
    public IEnumerable<string> GetJobsOfScheduler(string name)
    {
        if (_scedulers.ContainsKey(name))
        {
            foreach (var job in _scedulers[name])
            {
                yield return job.ToString();
            }
        }
    }
}

我发现您的抽象存在一些问题。。。看起来您抽象了队列,但没有抽象Job类。这应该是相反的(或者至少这样你的生活会轻松很多)。

public interface IJob
{
    MyJobType Type{ get; set; }
    string Name { get; set; }
    int Priority { get; set; }
    void RunJob();
}
  1. 您可以删除IQueue,因为您无论如何都没有使用它。

  2. 只使用一个队列,除非有充分的原因#3 没有解决

  3. 抽象你的工作类别——毕竟,制作奶酪三明治的工作与处理会议的工作不同。使用类似上面的接口,您可以按类型(您创建的枚举)和优先级对作业进行排序,然后使用IJob.RunJob运行它们,而不必知道它们在每个实现中实际做了什么。