2012-06-07 4 views
2

Можно создать дубликат:
What is the correct way to delay the start of a Task in c#C# задержка (асинхронной) исполнение без надежности перезапуске

Мне нужно планировать небольшие задачи, которые будут выполняться в будущем (задержка всегда < 1мин) , Реализация выполняется в .NET в среде выполнения .NET 4.0. Async ctp является вариантом, хотя я не вижу добавленную стоимость на данный момент.

  • планирование должно быть асинхронной
  • разрешения планирования в секундах
  • выполнение задачи неявно асинхронный (я думаю)
  • числа запланированных задач может быть в сотнях или даже тысячах
  • возможно, однако маловероятно, что две задачи будут запланированы в то же самое время

Мое текущее решение является это:

internal class TimerState 
{ 
    internal Timer Timer { get; set; } 
    internal object Payload { get; set; } 
    internal Action<object> Action { get; set; } 
} 

public class TimerModule 
{ 
    public static void ScheduleTask(object input, Action<object> action, TimeSpan delay) 
    { 
     //create state to pass to timer method 
     var state = new TimerState { Payload = input, Action = action }; 

     //schedule timer without firing 
     var t = new Timer(HandleScheduleTimer, state, -1, -1); 

     //add timer to state to be able to dispose it 
     state.Timer = t; 

     //schedule timer to fire in delay time 
     t.Change(delay, TimeSpan.FromMilliseconds(-1)); 
    } 


    private static void HandleScheduleTimer(object state) 
    { 
     var s = state as TimerState; 

     Task.Factory.StartNew(s.Action, s.Payload, CancellationToken.None, 
           TaskCreationOptions.PreferFairness, TaskScheduler.Current); 

     //dispose the timer immediately 
     if(s.Timer != null) 
      s.Timer.Dispose(); 
    } 
} 

Я сделал несколько тестов с счетчиками производительности (.NET физических потоков), но я не вижу, что много потоков, выполняющихся в то же время, даже если я планировать тысячи задач в приблизительно в то же время.

Есть ли лучший способ сделать это?

Есть ли проверенные образцы дизайна вокруг этого?

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

Edit: Я не имею в виду, что я хочу видеть тысячи потоков, работающих одновременно. Я знаю, что это, вероятно, будет обработано с помощью threadpool. Как я уже сказал в комментариях, тест с задачами 5M, охватываемыми более 100 секунд, видит только увеличение на 20 физических потоков.

Мой главный вопрос: есть ли лучший способ отложить выполнение задачи?

+0

Сколько потоков вы видите? и сколько ядер у вас есть? –

+0

Я запускаю задания 5M, запланированные на 100 секунд. У меня 3 ядра, и я вижу около 180 физических потоков (глобальный счетчик). содержание заданий будет выполняться в рамках второй части. Можно ли заменить работу сном в тесте? – stombeur

+1

Вы посмотрели: http://stackoverflow.com/questions/4990602/what-is-the-correct-way-to-delay-the-start-of-a-task-in-c-sharp? – Slugart

ответ

1

Решение, которое вы ищете, это кварц.

http://quartznet.sourceforge.net/

Это очень надежный планировщик, способный обрабатывать различные задания, привязанные к различным схемам. Он гораздо надежнее, чем таймер. У него есть отказ, если что-то пойдет не так.

Расписания либо используют интервал CRON, либо могут работать в определенные даты. Я слышал о случаях, когда тысячи рабочих мест. Кварц может быть сгруппирован, если необходимо, и может работать с сохранением состояния (сохраняя знания предыдущих экземпляров) и не-состояниями. В зависимости от того, как они настроены, они могут запускаться одновременно или в очереди. Большинство проблем с потоками и потоками позаботились о вас, вы можете написать свой класс работы без головной боли.

Настройка проста (установить сервис и настроить), создание кварцевых заданий еще проще. Создайте класс, который наследуется от IJob, примените вашу логику и добавьте ее в конфигурацию кварца. Config может представлять собой файл xml, базу данных sql-сервера или вы можете создать собственное решение. Я работаю над одним для RavenDB.

Смежные вопросы