添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams
public void ConfigureServices(IServiceCollection services) {
  services.AddHostedService<LifetimeEvents>();

where the LifeTimeEvents class inherits from IHostedService. I get this error:

'IServiceCollection' does not contain a definition for 'AddHostedService' and no extension method 'AddHostedService' accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?)

I can't seem to find the proper namespace to use or nuget package to include to get this working, but it worked out of the box in .NET Core 2.1, is this just not available in .NET Core 2.0? Is there any way to get it working?

UPDATE:

As a workaround I changed my code to use:

Startup.cs

public void ConfigureServices(IServiceCollection services) {
  services.AddSingleton<LifetimeEvents>();
public void Configure(IApplicationBuilder appBuilder, IHostingEnvironment envHost, LifetimeEvents appEvents)  {
  appEvents.StartAsync(new CancellationToken(false));

and that seems to have done the job. Doesn't answer my original question, and I'm not sure how "best practices" it is, but it did get me moving refactoring this .NET Core 2.0 app.

ServiceCollectionHostedServiceExtensions.AddHostedService(IServiceCollection) Method as shown in the API reference

Applies to
ASP.NET Core

However the source code is available on GitHub. You can easily check it out there and copy a local version to your 2.0 project

namespace Microsoft.Extensions.DependencyInjection
    public static class ServiceCollectionHostedServiceExtensions
        /// <summary>
        /// Add an <see cref="IHostedService"/> registration for the given type.
        /// </summary>
        /// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam>
        /// <param name="services">The <see cref="IServiceCollection"/> to register with.</param>
        /// <returns>The original <see cref="IServiceCollection"/>.</returns>
        public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services)
            where THostedService : class, IHostedService
            => services.AddTransient<IHostedService, THostedService>();

Source code

Ideally you could just update the project to 2.1 where the extension becomes available.

I believe this is a duplicate question to what I've answered before.

Where am I supposed to start persistent background tasks in ASP.NET Core?

Below is the answer, copy + pasted.

I believe you're looking for this

https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/

And i did a 2 hour self-proclaimed-award-winning hackathon against myself to learn abit of that.

https://github.com/nixxholas/nautilus

You can refer the injections here and implement the abstracts from there too.

Many MVC projects are not really required to operate persistent background tasks. This is why you don't see them baked into a fresh new project via the template. It's better to provide developers an interface to tap on and go ahead with it.

Also, with regards to opening that socket connection for such background tasks, I have yet to establish a solution for that. As far as I know/did, I was only able to broadcast payload to clients that are connected to my own socketmanager so you'll have to look elsewhere for that. I'll definitely beep if there is anything regarding websockets in an IHostedService.

Ok anyway here's what happens.

Put this somewhere in your project, its more of an interface for you to overload with to create your own task

/// <summary> /// Base class for implementing a long running <see cref="IHostedService"/>. /// </summary> 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; // 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();

Here's how you can actually use it

public class IncomingEthTxService : BackgroundService
        public IncomingEthTxService(IServiceScopeFactory scopeFactory) : base(scopeFactory)
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
            while (!stoppingToken.IsCancellationRequested)
                using (var scope = _scopeFactory.CreateScope())
                    var dbContext = scope.ServiceProvider.GetRequiredService<NautilusDbContext>();
                    Console.WriteLine("[IncomingEthTxService] Service is Running");
                    // Run something
                    await Task.Delay(5, stoppingToken);

If you noticed, there's a bonus there. You'll have to use a servicescope in order to access db operations because its a singleton.

Inject your service in

// Background Service Dependencies
            services.AddSingleton<IHostedService, IncomingEthTxService>();
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.