【发布时间】:2021-07-20 07:50:33
【问题描述】:
我正在尝试将服务构建到每小时运行的 .NET Core 3.1 应用程序中。我的服务每小时运行一次(即在StartAsync() 中遇到断点),但实现会立即引发以下错误:
任务被取消
我已经搜索了很多,但是我很难找到有用的答案;使用HttpClient 时似乎最常抛出这些问题,这与我的情况无关。
也就是说,我有一种预感,我应该等待某事,但我尝试添加 await 导致应用程序在启动时挂起(我想我无意中等待完整的每小时迭代...?)。 tutorial I've been following 不在任何地方使用await;除非有疏忽(很有可能),否则我的代码似乎与所示示例相同。
我已经抽出ExecuteAll() 的胆量来确认代码在工作中。
谢谢。
public Task StartAsync(CancellationToken cancellationToken)
{
TimeSpan interval = TimeSpan.FromHours(1);
var nextRunTime = DateTime.Today.AddHours(DateTime.UtcNow.Hour + 1);
var curTime = DateTime.UtcNow;
var firstInterval = nextRunTime.Subtract(curTime);
//Run once on startup
TriggerHourlyService(null);
void action()
{
//Schedule the first iteration
var t1 = Task.Delay(firstInterval);
t1.Wait();
TriggerHourlyService(null);
//Schedule hourly
_timer = new Timer(
TriggerHourlyService,
null,
TimeSpan.Zero,
interval
);
}
Task.Run(action);
return Task.CompletedTask;
}
private void TriggerHourlyService(object state)
{
using var scope = _serviceScopeFactory.CreateScope();
IHourlyService hourlyService = scope.ServiceProvider.GetRequiredService<IHourlyService>();
//ASYNC METHOD
hourlyService.ExecuteAll();
}
更新
在收到 cmets 的一些注释后,我稍微重写了代码以远离本教程(它似乎在宣传一些危险的做法)。但是,通过这种重写,我的应用程序在启动时挂起。我相信是 await Task.Delay(...) 导致了问题,但我的印象是这是非阻塞的。
public async Task StartAsync(CancellationToken cancellationToken)
{
TimeSpan interval = TimeSpan.FromHours(1);
var nextRunTime = DateTime.UtcNow.Date.AddHours(DateTime.UtcNow.Hour + 1);
var curTime = DateTime.UtcNow;
var firstInterval = nextRunTime.Subtract(curTime);
//Run once on startup
await TriggerHourlyService(null);
//First run on next hour
await Task.Delay(firstInterval);
await TriggerHourlyService(null);
//Schedule hourly
_timer = new Timer(
async (state) => await TriggerHourlyService(state),
null,
TimeSpan.Zero,
interval
);
}
private async Task TriggerHourlyService(object state)
{
using var scope = _serviceScopeFactory.CreateScope();
IHourlyService hourlyService = scope.ServiceProvider.GetRequiredService<IHourlyService>();
await hourlyService.ExecuteAll();
}
【问题讨论】:
-
告诉我更多关于您的服务的信息。您有一个连接到服务的客户端应用程序。告诉我客户端如何与服务通信?你有一个请求和一个响应。响应是
-
您能否详细说明或更直接地说明您的建议?我感觉有些隐晦的建议我没有接受。
-
我不想反对你。你说你没有HttpClient。您有一个客户端与服务器通信。所以有一个协议是用来通信的。它可以是任何东西,但现在大多数情况下是 HTTP。所以我需要更多关于协议的信息。
-
如果该方法
hourlyService.ExecuteAll();没有阻塞,那么您的服务提供者和由它创建的所有内容都会在该方法内部的任何内容运行之前被处置。此外,您的代码可能会通过调用:t1.Wait();陷入死锁。你应该重建那块,这样你就可以正确地await它。 -
@Santi --
IHostedService被注入 as transient。
标签: c# .net-core asp.net-core-hosted-services