System.InvalidOperationException:无法使用单例“ Microsoft.Extensions.Hosting.IHostedService”中的作用域服务“ MyDbContext”

时间:2018-07-31 15:17:01

标签: c# asp.net asp.net-mvc asp.net-web-api asp.net-core-2.0

我为ASP.NET Core 2.1 Web App成功实现了后台任务,今天突然停止了工作,给我一个错误:

  

System.InvalidOperationException:无法使用作用域服务   单例的“ MyDbContext”   “ Microsoft.Extensions.Hosting.IHostedService”

我知道关于该问题的话题很少,而且我已经阅读了有关此错误的内容,但我认为我的工作人员已正确实施。我正在创建范围服务,并且一直成功地工作到今天。 我的实现类似于本教程中的实现:https://shortly.cc/EIxe

背景任务代码:

public class OnlineTagger : Core.BackgroundService
    {
        private readonly CoordinatesHelper _coordinatesHelper;

        public OnlineTagger(IServiceScopeFactory scopeFactory, CoordinatesHelper coordinatesHelper) : base(scopeFactory)
        {
            _coordinatesHelper = coordinatesHelper;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {

            while (!stoppingToken.IsCancellationRequested)
            {
                using (var scope = _scopeFactory.CreateScope())
                {
                    var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();

                    Console.WriteLine("Online tagger Service is Running");

                    // Run something
                    await ProcessCoords(dbContext);

                    // Run every 30 sec
                    await Task.Delay(30000, stoppingToken);
                }
            }
        }

        private async Task ProcessCoords(MyDbContext dbContext)
        {
            var topCoords = await _coordinatesHelper.GetTopCoordinates();

            foreach (var coord in topCoords)
            {
                var user = await dbContext.Users.SingleOrDefaultAsync(c => c.Id == coord.UserId);

                if(user != null)
                {
                    var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    //expire time = 120 sec
                    var coordTimeStamp = DateTimeOffset.FromUnixTimeMilliseconds(coord.TimeStamp).AddSeconds(120).ToUnixTimeMilliseconds();

                    if (coordTimeStamp < now && user.IsOnline == true)
                    {
                        user.IsOnline = false;
                        await dbContext.SaveChangesAsync();
                    }
                    else if(coordTimeStamp > now && user.IsOnline == false)
                    {
                        user.IsOnline = true;
                        await dbContext.SaveChangesAsync();
                    }
                }
            }
        }
    }

基类:

    public abstract class BackgroundService : IHostedService, IDisposable
{
    protected readonly IServiceScopeFactory _scopeFactory;
    private Task _executingTask;
    private readonly CancellationTokenSource _stoppingCts =
                                                   new CancellationTokenSource();

    public BackgroundService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

    public virtual Task StartAsync(CancellationToken cancellationToken)
    {
        // Store the task we're executing
        _executingTask = ExecuteAsync(_stoppingCts.Token);

        // If the task is completed then return it,
        // this will bubble cancellation and failure to the caller
        if (_executingTask.IsCompleted)
        {
            return _executingTask;
        }

        // Otherwise it's running
        return Task.CompletedTask;
    }

    public virtual async Task StopAsync(CancellationToken cancellationToken)
    {
        // Stop called without start
        if (_executingTask == null)
        {
            return;
        }

        try
        {
            // Signal cancellation to the executing method
            _stoppingCts.Cancel();
        }
        finally
        {
            // Wait until the task completes or the stop token triggers
            await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite,
                                                          cancellationToken));
        }
    }

    public virtual void Dispose()
    {
        _stoppingCts.Cancel();
    }
}

Startup.cs:

services.AddSingleton<Microsoft.Extensions.Hosting.IHostedService, OnlineTagger>();

0 个答案:

没有答案