在我正在创建的应用程序中,我希望有一个调度程序,其中包含有关传入作业的数据以及执行它们的剩余时间,因此我创建了一个非常幼稚的实现,我认为它远不应该是什么
接口
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();
这段代码是否运作良好,或者我只是错过了所有的东西,并且有更好的方法来做这样的事情?
请问我想要一个非常详细的答案,说明我提供的代码的缺点是什么,以及如何创建更好的重用代码(仅适用于可能会发现此主题有用的其他人)。
答案 0 :(得分:2)
正如您可以通过使用看到的那样,在调度程序中使用调度程序的名称会使代码变得有点时髦......调度程序是否真的需要知道自己的名字?我会改用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();
}
}
}
}
答案 1 :(得分:0)
我看到你的抽象问题......似乎你抽象队列,而不是Job类。这应该是相反的(或者至少你的生活会更容易)。
public interface IJob
{
MyJobType Type{ get; set; }
string Name { get; set; }
int Priority { get; set; }
void RunJob();
}
您可以删除IQueue,因为您还没有使用它。
只使用一个队列,除非有充分的理由没有通过#3
摘要你的工作类 - 毕竟创建奶酪三明治的工作与处理会议的工作不同。通过上面的界面,您可以按类型(您创建的枚举)和优先级排序作业,然后使用IJob.RunJob运行它们,而无需知道它们在每个实现中实际执行的操作。