尝试使用:
Startup.cs
public void ConfigureServices(IServiceCollection services) {
services.AddHostedService<LifetimeEvents>();
.
.
.
}
LifeTimeEvents类从IHostedService继承的位置。我收到此错误:
'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?)
我似乎找不到合适的名称空间来使用或使用nuget包来使其正常工作,但是它在.NET Core 2.1中是开箱即用的,.NET Core 2.0中是否不可用?有什么方法可以使其正常工作吗?
更新:
作为解决方法,我将代码更改为使用:
Startup.cs
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton<LifetimeEvents>();
.
.
.
}
public void Configure(IApplicationBuilder appBuilder, IHostingEnvironment envHost, LifetimeEvents appEvents) {
appEvents.StartAsync(new CancellationToken(false));
.
.
.
}
这似乎已经完成了工作。无法回答我最初的问题,也不确定它的“最佳实践”如何,但这确实让我着手重构此.NET Core 2.0应用。
答案 0 :(得分:2)
.NET Core 2.0不能使用此功能吗?
ServiceCollectionHostedServiceExtensions.AddHostedService(IServiceCollection) Method,如API参考
所示适用于
ASP.NET Core
2.1
但是源代码在GitHub上可用。您可以轻松地将其检出,然后将本地版本复制到您的2.0项目中
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>();
}
}
理想情况下,您可以将项目更新到可用扩展名的2.1。
答案 1 :(得分:0)
我相信这是我之前回答过的重复问题。
Where am I supposed to start persistent background tasks in ASP.NET Core?
下面是答案,请复制+粘贴。
我相信您正在寻找这个
然后我对自己进行了两个小时的自称获奖的黑客马拉松,以了解其中的一点。
https://github.com/nixxholas/nautilus
您可以在此处引用注入并从那里实现摘要。
实际上并不需要许多MVC项目来运行持久性后台任务。这就是为什么您看不到通过模板将它们烘焙到新的新项目中的原因。最好为开发人员提供一个可以点击并继续使用它的界面。
此外,关于为此类后台任务打开该套接字连接,我尚未为此建立解决方案。据我了解/了解,我只能将有效负载广播到连接到我自己的套接字管理器的客户端,因此您必须在其他地方查找。如果IHostedService中有关于WebSocket的任何内容,我一定会发出哔哔声。
好吧,这就是发生的事情。
将此内容放置在项目中的某个位置,更多的是供您重载以创建自己的任务的界面
/// Copyright(c) .NET Foundation.Licensed under the Apache License, Version 2.0.
/// <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;
}
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();
}
}
这是您实际使用它的方式
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);
}
}
}
}
如果您注意到了,那儿会有一笔奖金。您必须使用servicescope才能访问数据库操作,因为它是单例的。
在以下位置注入服务
// Background Service Dependencies
services.AddSingleton<IHostedService, IncomingEthTxService>();