2010-09-30 41 views
1

我试图使用并行任务库揭开序幕像这样的一些任务:并行任务的建议

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的时刻是传递到StartNew作为这样一个变量的操作:

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

我听说了Thread.Sleep是一个不好解决这个。任何人都可以推荐更好的方法?

回答

0

不好的解决办法是Task在这里。 Task应该用于短期生活操作,如异步IO。如果你想控制任务的生命周期,你应该使用Thread并尽可能地睡觉,因为Thread是单独的,但Task s在共享的线程池中轮换。

+0

您可以指定TaskCreationOptions.LongRunning,创建一个新的线程,而不是使用线程池的任务。 – 2012-08-20 09:37:15

2

根据我的理解,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(); 
    } 
}