我相信这是我之前回答的重复问题。
Where am I supposed to start persistent background tasks in ASP.NET Core?
下面是答案,复制+粘贴。
我相信你正在寻找这个
https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/
我对自己进行了 2 小时自称获奖的黑客马拉松,以了解这一点。
https://github.com/nixxholas/nautilus
您可以在此处参考注入并从那里实现摘要。
许多 MVC 项目并不真正需要操作持久的后台任务。这就是为什么您看不到它们通过模板融入新项目的原因。最好为开发者提供一个界面,让他们可以点击并继续使用它。
此外,关于为此类后台任务打开该套接字连接,我还没有为此建立解决方案。据我所知/所做的,我只能将有效负载广播到连接到我自己的 socketmanager 的客户端,所以你必须在别处寻找。如果 IHostedService 中有任何关于 websockets 的信息,我肯定会发出哔哔声。
好吧,这就是发生的事情。
把它放在你的项目中,它更像是一个让你重载以创建自己的任务的界面
/// 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);
}
}
}
}
如果你注意到了,那里有一个奖励。您必须使用服务范围才能访问数据库操作,因为它是单例的。
注入你的服务
// Background Service Dependencies
services.AddSingleton<IHostedService, IncomingEthTxService>();