当使用async时,辅助服务进程在没有明显原因的情况下停止



我已经建立了一个非常简单的工作服务项目,只需要一个工人(目前(。以下是ExecuteAsync方法的完整代码:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
var engine = new CrawlerEngine(_logger);
try
{
await engine.CrawlAsync(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
}
await Task.Delay(TimeSpan.FromMinutes(1));
}
_logger.LogInformation("Worker stopping at: {time}", DateTimeOffset.Now);
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
}
}

正如你所看到的,它相当简单,只是一个无限循环,直到取消,其中唯一真正的逻辑都封装在CrawlerEngine中。

问题是,如果我运行该服务,它可能会运行几分钟,然后退出。它不会记录";工人停止";也不是例外,它只是简单地停止了整个过程。

我尝试更改CrawlAsync中的所有异步代码,因此它是完全同步的。这消除了问题,让我感到困惑。

CrawlAsync中的每个Async方法都返回Task或Task并等待。

所以我想,也许一些异步代码抛出了一个try-catch没有捕获的异常,但据我所知,该异常应该是";冒泡";只要你在使用wait就会被抓住。

我甚至添加了一个AppDomain.UnhandledException处理程序,它也不会捕获任何内容。

你知道这里到底发生了什么吗?

编辑:只是为了澄清一下,我想问异步是否有任何隐藏的细节,这可能会导致它在整个过程中崩溃,而没有多少try-catch能够看到它?

编辑2:似乎是WebClient.DownloadStringAsTaskAsync和HttpClient.GetStringAsync使我的进程崩溃。每当我使用其中一个时,我的进程就会在某个时刻退出。使用同步方法下载字符串不会导致这种情况

我终于弄清楚了退出进程的原因:StackOverflowException。

这解释了缺乏日志记录等的原因。我已经通过将递归方法(称为HttpClient.GetStringAsync(更改为for循环来解决了这个问题。

为什么它在使用GetString的非异步变体时没有抛出StackOverflow,我仍然无法理解。

相关内容

最新更新