长期运行的任务或线程?

Ana*_*eer 4 c# multithreading task-parallel-library

我有一个运行两种方法的Windows服务; 一个人使用该Ae.Net.Mail库每5分钟从三个电子邮件帐户中读取未读电子邮件(我们称之为EmailParserWorker),另一个方法每30分钟另一个未指定的工作.因为这些方法必须每X次运行一次,所以我用a 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

usr*_*usr 8

LongRunning有效地意味着"总是立刻开始一个新线程".这没有记录,但出于兼容性原因,这种行为永远不会改变.

你应该使用TaskLongRunning.这是严格优越的Thread.特别是错误处理和组合要好得多.

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

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

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

  • "LongRunning"表示仅用于默认任务调度程序的新线程.任何其他任务调度程序都可以忽略此选项,因为它不是必需的,而只是一个提示.例如,同步上下文任务调度程序`TaskScheduler.FromCurrentSynchronizationContext()`忽略它,只使用捕获的同步上下文中的`Post`方法. (2认同)