Spa*_*key 5 c# hangfire .net-core asp.net-core
在我的Web应用程序(ASP.NET Core)中,我想在后台运行一个正在侦听远程服务器的作业,计算一些结果并将其推送到Pusher上的客户端(websocket).
我不确定我应该在哪里开始这个任务.目前我在最后开始
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
Run Code Online (Sandbox Code Playgroud)
在Startup.cs中
但我觉得这有点不对,在一个名为"Configure"的方法中启动后台作业是没有意义的.我期待在某个地方找到一个Start方法
此外,当我尝试使用EF Core 生成初始数据库迁移文件时,它实际上执行该方法并启动我的任务..这显然没有任何意义:
dotnet ef migrations add InitialCreate
Run Code Online (Sandbox Code Playgroud)
从控制台运行它会创建迁移代码,该代码将用于根据我的数据模型在SQL Server上创建数据库.
为什么没有一种方法我可以开始一个任务?我不希望这是一个单独的进程,它实际上不需要自己的进程,它本质上是Web服务器的一部分,因为它确实通过websocket与客户端(浏览器)进行通信,所以它是有道理的将其作为Web服务器的一部分运行.
我相信你在寻找这个
我做了一个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();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是您实际使用它的方法
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你注意到,那里有奖金.您必须使用服务范围才能访问数据库操作,因为它是一个单例.
注入您的服务
// Background Service Dependencies
services.AddSingleton<IHostedService, IncomingEthTxService>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2733 次 |
| 最近记录: |