长期运行的任务或线程?

时间:2015-04-13 17:07:26

标签: c# multithreading task-parallel-library

我有一个运行两种方法的Windows服务;一个人使用Ae.Net.Mail库每5分钟从三个电子邮件帐户中读取未读电子邮件(我们称之为EmailParserWorker),另一个方法每30分钟另一个未指定的工作。因为这些方法必须每X次运行一次,所以我使用Timer来管理它们,它们运行正常。

private Timer mailParserTimer;
private readonly TimeSpan SLEEP_TIME_MAIL_PARSER = TimeSpan.FromSeconds(300d);

/*...*/

public MyService()
{
    ServiceName = _serviceName;
    mailParserTimer = new Timer(new TimerCallback(EmailParserWorker), null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
}
public void StartService()
{
    mailParserTimer.Change(SLEEP_TIME_MAIL_PARSER, Timeout.InfiniteTimeSpan);
    //EmailAnalyzer is a custom class I use to manage the accounts
    ea1 = new EmailAnalyzer(Config1); 
    ea2 = new EmailAnalyzer(Config2); 
    ea3 = new EmailAnalyzer(Config3); 
}

protected void EmailParserWorker(object state)
{
    try
    {
        // Pause timer during processing so it won't be run twice if the processing takes longer than the interval
        mailParserTimer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);

        // MANAGE THE THREE EMAIL ACCOUNTS
    }
    catch (Exception ex)
    {
        log.Error("[EmailParserWorker] Exception caught:" + ex.Message, ex.InnerException);
    }

    // Launch again in the specified time
    mailParserTimer.Change(SLEEP_TIME_MAIL_PARSER, Timeout.InfiniteTimeSpan);
}

我的问题是我必须管理三个电子邮件帐户。我的经理让我使用线程,以便他们可以同时运行,在调查了ThreadsTasks后,我很困惑哪个是我最好的选择。我知道ThreadPooling是不可能的,因为我读到某个地方,如果操作持续时间超过几秒钟,那么不应该使用那些(我当然会这样做);但Task不使用此功能?我知道它有一个LongRunning选项,但我不知道我的进程是否合格。然后有Threads,应该能够毫无问题地处理这个问题,但我不知道它在CPU使用方面是否会非常低效。

基本上,我不知道应该使用哪一种。现在我倾向于Tasks,但我不知道是否应该指定LongRunning标记。而且,如果相关,这些线程或任务将在使用计时器的方法内运行的事实是否会影响任何事情?

1 个答案:

答案 0 :(得分:8)

LongRunning实际上意味着"始终立即开始一个新主题"。这没有记录,但出于兼容性原因,这种行为永远不会改变。

您应该使用TaskLongRunning。这严格优于Thread。特别是错误处理和组合要好得多。

启动和销毁线程只需几毫秒。像1ms左右。不要担心开始3个线程。

  

事实上这些线程或任务将在使用计时器的方法内运行会影响任何事情吗?

他们将在计时器方法中运行。计时器方法将启动快速操作的任务。计时器刻度回调在线程池上运行。这不是一个问题,因为您正在将工作卸载到专用线程。