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