在ASP.NET Core托管服务中使用后台任务的while循环和事件遇到一些麻烦。我正在尝试从while (!cancellationToken.IsCancellationRequested)
部分触发我的Progress_Changed事件,以便在应用程序运行时连续捕获数据。我一直在遵循这些指南:
Background tasks with hosted services in ASP.NET Core
Implement background tasks in microservices with IHostedService and the BackgroundService class
如何在将BackgroundService保持连续循环的同时捕获事件,以便始终能够获取数据?我希望将其与SignalR一起使用,以便将数据馈送到集线器。
public class MyBackgroundService : BackgroundService
{
private readonly ICustomService _service;
private IProgress<JSONMessage> _progress;
public MyBackgroundService(ICustomService service)
{
_service = service;
_progress = new Progress<JSONMessage>();
_progress.ProgressChagned += Progress_Changed;
{
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
await _service.StartService(_progress);
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}
private void Progress_Changed(object s, JSONMessage e)
{
Console.WriteLine(e.Id);
}
}
答案 0 :(得分:0)
由于各种原因,在IIS中长时间运行任务可能会很棘手。将此类内容委派给像Hangfire这样的可以正常工作的库可能更容易。 https://www.hangfire.io/。
答案 1 :(得分:0)
我可能是错的,但这对我来说似乎是一个僵局。默认情况下,await
会捕获当前的SynchronizationContext
,然后在完成后将其发布回去。出于很多原因,我在IIS / ASP.NET中会遇到很多麻烦。请尝试以下代码:
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
await _service.StartService(_progress).ConfigureAwait(false);
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
}
}
这里所做的唯一更改是禁用回发到我所说的捕获上下文。请注意,这意味着在调用await
之后,您可能处于不同的线程上。因此,您可以将其视为黑客行为,但是在需要回发的方法中,我看不到任何东西。
如果不能解决问题,我会将调试器附加到 release 版本。或使用探查器查看实际发生的情况。