优雅地停止Timer回调工作线程

时间:2010-10-14 23:58:01

标签: .net windows-services timer threadpool

我在Windows服务中使用System.Threading.Timer并使用Monitor.TryEnter锁定回调方法,因此它不可重入。在回调中,我循环一些数据库对象(Linq到SQL实体)并执行一些IO任务。在循环的每次迭代中,我正在更改实体的一些属性以将其标记为已处理。循环退出后,我在datacontext上调用SubmitChanges,这会将更改保留到数据库中。出现以下问题:如果在执行回调时服务已停止,则某些IO任务可能已执行,但记录尚未在数据库中标记为已处理(即尚未调用SubmitChanges) - 显然,不是我想要发生的事情。不知何故,我需要与回调工作线程进行通信,OnStop事件已经触发,以允许它提交更改并进行包装。怎么做到最好?

2 个答案:

答案 0 :(得分:1)

1决定你是否完成回调执行的任务,否则你将回滚它们。因此,如果您决定完成任务,您将执行回调结束。应该在OnStop中取消时间。如果您使用第二个选项(回滚),您的代码将看起来像这样:

bool shouldAbort=false;

TimerProc()
{
     Step1();
     if (shouldAbort)
     {
         UndoStep1();
         return;
     }
     Step2();
     if (shouldAbort)
     {
         UndoStep2();
         UndoStep1();  //  or vice versa, depending on your operations
         return;
     }
     // ...
}
在OnStop()中

timer.Stop();  //  don't worry here - your TimerProc() WILL finish
shouldAbort=true;

答案 1 :(得分:0)

您可以使用Task Parallel Library查看。阅读Task Cancellation页面。如果我已正确理解您的需求,这将为您提供一种创建工作线程的方法,这些线程可以根据取消进行整洁整理。