如何解决任务应如何正确指示Windows服务关闭?
我正在研究Windows服务的错误。该服务使用一个字段来跟踪对单个任务的引用。 OnStart,任务执行单个方法。该方法内部有一个循环,并以可配置的间隔调用数据库以监视另一个系统正在执行的工作。
protected override void OnStart(string[] args)
{
_processorTask = Task.Run(() => StartProcessor());
}
我们偶尔会遇到一个问题,即Task死掉并记录异常情况很好,但是现有的管道并没有告诉服务停止,因此我们的服务监视器不知道有什么问题。
private void StartProcessor()
{
var processor = new PEMonitoringProcessor(_tokenSource.Token);
try
{
// The process loop is in the function. If this method exits,good or bad,the service should stop.
processor.ProcessRun();
}
catch (Exception ex)
{
// An exception caught here is most likely fatal. Log the ex and start the service shutdown.
if (log.IsFatalEnabled) { log.Fatal("A Fatal error has occurred.",ex); };
}
finally
{
Stop();
}
}
但是,我的一位开发人员注意到OnStop方法中使用了一个令牌来指示Task停止然后等待。如果Task调用Stop并等待Stop返回并且OnStop正在等待Task结束,则对于此代码而言,这不是好兆头。
protected override void OnStop()
{
_tokenSource.Cancel();
try
{
_processorTask.Wait();
}
// logging & clean-up...
}
我考虑了一个单独的任务,它不会被OnStop等待,它会检查第一个任务的状态,并在第一个任务完成,出现故障等情况下调用Stop,但这似乎有点不可思议。我还考虑过举办活动并尝试类似BeginInvoke的事情。
故意停止服务可以正常工作,因为OnStop通过Token发出信号,表明正在关闭。我试图解决Task方法返回或意外抛出并且我希望服务停止而不是变成僵尸的可能性。
解决方法
我看到的最直接的方式是这样的:
protected override void OnStart(string[] args) {
_processorTask = Task.Run(() => StartProcessor());
_processorTask.ContinueWith(x => {
// x.Exception contains exception if any,maybe log it here
Stop();
},TaskContinuationOptions.NotOnCanceled);
}
protected override void OnStop() {
//or !_processorTask.IsCompleted && !_processorTask.IsCanceled && !_processorTask.IsFaulted
if (_processorTask.Status == TaskStatus.Running) {
// only cancel and wait if still running. Won't be the case if service is stopping from ContinueWith above
_tokenSource.Cancel();
_processorTask.Wait();
}
}
执行此操作的替代方法:
protected override async void OnStart(string[] args) {
_processorTask = Task.Run(() => StartProcessor());
bool cancelled = false;
try {
await _processorTask;
}
catch (OperationCanceledException) {
// cancelled
cancelled = true;
}
catch (Exception ex) {
// log it?
}
if (!cancelled)
Stop();
}
// OnStop stays the same
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。