问题
I have a table of schedule items, they may be scheduled for the same time. I'm wondering how to have them all execute at the correct time when:
The problem I see is that executing one scheduled item (like a scheduled twitter post) requires an API request which may take up to a second or two - probably longer. If I execute them sequentially + there are too many scheduled items at the same time, the time they get executed at could be after the scheduled time.
How would I go about building this "scheduling" system that avoids these problems? Any tips, advice?
Thanks!
回答1:
I would use a Windows service to accomplish this. Then each of the items should be scheduled asynchronously using the BackgroundWorker process. This would allow all of the scheduled processes to be launched rapidly asynchronously so they don't collide and aren't depending on the previous one finishing before kicking off.
回答2:
You might want to consider Quartz.NET. Gives you much flexibility in terms of scheduling and task execution.
回答3:
Unless you take steps to take advantage of the asynchronous APIs that exist for all IO operations, your only approach is to use many threads. Consider the .net ThreadPool as this can increase the number of threads when too many work items are queued. There will be a limit here, as the ThreadPool spins up extra threads relatively slowly. Under sustained overload, your system will groan. Like I said, the best way to approach this is with asynchronous IO.
回答4:
You can put the tasks in threads when you get want them to run:
public abstract class MyTask {
public abstract void DoWork();
}
// ...
public void SomeTaskStarter()
{
MyTask task = SomeFactoryMethodToCreateATaskInstance();
new Thread(new ThreadStart(task.DoWork)).Start();
}
MyTask is an abstract class that represents a task to do and it defines a method, DoWork() that will do what you want. SomeFactoryMethodToCreateATaskInstance() will construct a concrete instance of a task and all you need to do is write DoWork() to do what you need to do:
public class Twitterer : MyTask
{
private string _tweet;
public Twitterer(string tweet)
{
_tweet = tweet;
}
public override DoWork()
{
TwitterApi api = new TwitterApi(); // whatever
api.PostTweet(tweet);
}
}
You will most assuredly want some kind of action of task completion. Whatever you do, the task completion routine should be threadsafe, and should probably be called via BeginInvoke()/EndInvoke() if you need to do any UI-ish work.
SomeTaskStarter() is best called from a windows service, and will most likely contain an argument with information about what task should be started, etc.
来源:https://stackoverflow.com/questions/2136983/how-create-a-scheduler-e-g-to-schedule-tweets-or-an-api-request