Параллельное задание - PullRequest
       4

Параллельное задание

1 голос
/ 30 сентября 2010

Я пытаюсь использовать библиотеку параллельных задач, чтобы запустить ряд задач, таких как:

var workTasks = _schedules.Where(x => x.Task.Enabled);   
_tasks = new Task[workTasks.Count()];    
_cancellationTokenSource = new CancellationTokenSource();       
_cancellationTokenSource.Token.ThrowIfCancellationRequested();    

int i = 0;    
foreach (var schedule in _schedules.Where(x => x.Task.Enabled))
{
    _log.InfoFormat("Reading task information for task {0}", schedule.Task.Name);    
    if(!schedule.Task.Enabled)
    {
        _log.InfoFormat("task {0} disabled.", schedule.Task.Name);    
        i++;    
        continue;   
    }

    schedule.Task.ServiceStarted = true;    
    _tasks[i] = Task.Factory.StartNew(() =>
            schedule.Task.Run()
        , _cancellationTokenSource.Token);                        
    i++;    
    _log.InfoFormat("task {0} has been added to the worker threads and has been started.", schedule.Task.Name);
}

Я хочу, чтобы эти задачи спали, а затем просыпались каждые 5 минут и делали свое дело, вв тот момент, когда я использую Thread.Sleep в объекте Schedule, чей метод Run является действием, которое передается в StartNew в качестве аргумента, подобного следующему:

_tasks[i] = Task.Factory.StartNew(() =>
        schedule.Task.Run()
    , _cancellationTokenSource.Token);

Я где-то читал, что Thread.Sleep является плохим решением дляэтот.Кто-нибудь может порекомендовать лучший подход?

Ответы [ 2 ]

2 голосов
/ 17 мая 2011

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

У меня есть привычка использовать этот фрагмент вместо:

new System.Threading.EventWaitHandle(false, EventResetMode.ManualReset).WaitOne(1000);

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

В любом случае, если вы просто пытаетесь повторять что-то каждые 5 минут, лучше использовать таймер. Вы могли бы даже сделать класс, чтобы аккуратно обернуть все, если ваши повторяющиеся методы работы уже учтены:

using System.Threading;
using System.Threading.Tasks;
public class WorkRepeater
{
    Timer m_Timer;

    WorkRepeater(Action workToRepeat, TimeSpan interval)
    {
        m_Timer = new System.Timers.Timer((double)Interval.Milliseconds);
        m_Timer.Elapsed += 
            new System.Timers.ElapsedEventHandler((o, ea) => WorkToRepeat());
    }

    public void Start()
    {
        m_Timer.Start();
    }

    public void Stop()
    {
        m_Timer.Stop();
    }
}
0 голосов
/ 30 сентября 2010

Плохое решение - Task с здесь. Task следует использовать для кратковременных операций, таких как асинхронный ввод-вывод. Если вы хотите контролировать время жизни задачи, вы должны использовать Thread и спать сколько хотите, потому что Thread индивидуально, но Task s вращаются в пуле потоков, который является общим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...