基于ASP.NET Core事件的托管服务后台任务

问题描述 投票:0回答:2

我在使用ASP.NET Core托管服务中的后台任务的while循环和事件时遇到了一些麻烦。我试图让我的Progress_Changed事件从while (!cancellationToken.IsCancellationRequested)部分中触发,这样我就可以在应用程序运行时连续捕获数据。我一直在关注这些指南:

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);
    }
}
c# asp.net asp.net-core signalr asp.net-core-2.0
2个回答
0
投票

由于各种原因,在IIS中长时间运行任务可能很棘手。将这种东西委托给像Hangfire一样工作的库可能更容易。 https://www.hangfire.io/


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之后,您可能处于不同的线程中。因此你可以认为这是一个黑客,但我在方法中看不到任何需要回发的内容。

如果这不能解决问题,我会将调试器附加到发布版本中。或者使用分析器查看究竟发生了什么。

© www.soinside.com 2019 - 2024. All rights reserved.