Как создать планировщик (например, чтобы запланировать твиты или запрос API) - PullRequest
4 голосов
/ 26 января 2010

У меня есть таблица элементов расписания, они могут быть запланированы на одно и то же время. Мне интересно, как заставить их все выполняться в правильное время, когда:

Проблема, которую я вижу, состоит в том, что для выполнения одного запланированного элемента (например, запланированного поста в Твиттере) требуется запрос API, который может занимать до одной или двух секунд - возможно, больше Если я выполняю их последовательно + слишком много запланированных элементов одновременно, время, когда они выполняются, может быть позже запланированного времени.

Как мне поступить при создании этой системы "планирования", которая позволит избежать этих проблем? Любые советы, советы?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 26 января 2010

Я бы использовал службу Windows для этого. Затем каждый из элементов должен планироваться асинхронно с использованием процесса BackgroundWorker. Это позволило бы быстро запускать все запланированные процессы асинхронно, чтобы они не сталкивались и не зависели от предыдущего, завершившегося до запуска.

3 голосов
/ 26 января 2010

Возможно, вы захотите рассмотреть Quartz.NET . Предоставляет вам большую гибкость в плане планирования и выполнения задач.

1 голос
/ 26 января 2010

Если вы не предпримете шаги, чтобы воспользоваться преимуществами асинхронных API, которые существуют для всех операций ввода-вывода, ваш единственный подход - использовать много потоков. Рассмотрим .net ThreadPool, так как это может увеличить количество потоков, когда слишком много рабочих элементов поставлено в очередь. Здесь будет ограничение, так как ThreadPool раскручивает дополнительные потоки относительно медленно. При длительной перегрузке ваша система будет стонать. Как я уже сказал, лучший способ добиться этого - асинхронный ввод-вывод.

0 голосов
/ 26 января 2010

Вы можете помещать задачи в потоки, когда хотите, чтобы они выполнялись:

public abstract class MyTask {
    public abstract void DoWork();
}


// ...

public void SomeTaskStarter()
{
    MyTask task = SomeFactoryMethodToCreateATaskInstance();

    new Thread(new ThreadStart(task.DoWork)).Start();
}

MyTask - это абстрактный класс, который представляет задачу для выполнения, и он определяет метод DoWork (), который будет делать то, что вы хотите. SomeFactoryMethodToCreateATaskInstance () создаст конкретный экземпляр задачи, и все, что вам нужно сделать, это написать DoWork (), чтобы сделать то, что вам нужно сделать:

public class Twitterer : MyTask
{
    private string _tweet;
    public Twitterer(string tweet)
    {
        _tweet = tweet;
    }
    public override DoWork()
    {
        TwitterApi api = new TwitterApi(); // whatever
        api.PostTweet(tweet);
    }
}

Вы наверняка захотите какое-то действие по завершению задачи. Что бы вы ни делали, подпрограмма завершения задачи должна быть поточно-ориентированной и, вероятно, должна вызываться через BeginInvoke () / EndInvoke (), если вам нужно выполнить какую-либо работу с пользовательским интерфейсом.

SomeTaskStarter () лучше всего вызывать из службы Windows и, скорее всего, будет содержать аргумент с информацией о том, какую задачу следует запустить и т. Д.

...