c# - 为什么windows服务OnStart()中的Task.Run()会导致服务拒绝停止?
问题描述
我不确定为什么这项服务拒绝停止。
我在尝试纠正TimeoutException
启动服务时抛出的问题时遇到了这个问题。使用:
public void OnStart()
{
_startTask = Task.Run(DoWork, _cancelTokenSource.Token);
}
private void DoWork(){ [listen for things and operate on them] }
public void OnStop()
{
_cancelTokenSource.Cancel();
_startTask.Wait();
}
我知道实现一个简单的计时器可以解决这个问题,但这不是我的问题的重点。为什么使用Task.Run(() => action, _tokenSource.Token)
resolve the TimeoutException
but会导致服务不响应控制消息?
观察到的问题
安装并启动服务(它是TopShelf BTW)后,我无法通过常规方法停止服务。
第一次尝试:
所有后续尝试:
编辑:仍然没有快乐
这是我在遵循提供的示例之后的尝试。
public void Start()
{
var token = _cancelTokenSource.Token;
Task.Factory.StartNew(() => Setup(token), token);
}
public void Stop()
{
_cancelTokenSource.Cancel();
//TearDown(); <-- original implementation of stop
}
private void Setup(CancellationToken token)
{
_mailman.SendServiceStatusNotification(_buildMode, "Started");
... create some needed objects
token.Register(TearDown);
InitializeInboxWatcherProcess(...);
}
private void TearDown()
{
_inboxWatcher.Terminate();
_mailman.SendServiceStatusNotification(_buildMode, "Stopped");
}
private void InitializeInboxWatcherProcess(...)
{
// pre create and initiate stuff
_inboxWatcher = new LocalFileSystemWatcherWrapper(...);
_inboxWatcher.Initiate();
}
public class LocalFileSystemWatcherWrapper : IFileSystemWatcherWrapper
{
// do FileSystemWatcher setup and control stuff
}
解决方案
这很可能是因为您没有取消方法,或者DoWork()
当您调用Cancel()
. 正如@Damien_The_Unbeliever 所说,取消是一项合作任务。
如果您还没有注册回调函数,那么当您调用_cancelTokenSource.Cancel()
时,所有发生的事情都是布尔值isCancellationRequested
设置为 true,DoWork()
然后该方法负责查看并自行停止其执行。DoWork()
但是,这里有一个缺陷,您可能会说,如果您在调用时在任务中运行了一个耗时的循环Cancel()
,则该循环必须完成一次迭代,然后才能检查isCancellationRequested
可能导致挂起的值.
解决这个问题的方法是在方法中插入取消回调函数DoWork()
,请参见此处,然后将它们注册到令牌中,这样当您调用该Cancel()
方法时,后台运行的所有任务都将停止,而无需等待它们。
希望这可以帮助!
推荐阅读
- python - 如何通过 scipy.derivative 方法正确使用 lambda 表达式?
- c++ - CodeBlocks C++ 程序未运行
- elasticsearch - ElasticSearch:存在模板时将文档插入 ElasticSearch 索引的奇怪问题
- java - 比较扩展 Comparable 的两个对象的正确方法
- php - Laravel 将 DB 字段设置为空数组
- godot - Godot - 混淆的 Tilemap 象限大小
- ssas - 处理多维数据集 - 错误 - 连接到系统的设备无法正常工作
- javascript - 如何在 laravel 中将可共享链接设为公开
- flutter - 可拖动的小部件不会落在确切的位置 Flutter
- r - 无法为签名“字符”找到函数“物种”的继承方法