我的aspnet核心应用需要在指定的时间间隔内抓取数据。我选择实现IHostedService使其与api并行运行。此托管服务需要注入一些服务。现在我在启动时注册它们,但出现此错误:
System.InvalidOperationException:'无法从单例'Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor'中使用作用域服务'IXService'。
我的startup.cs:
services.AddScoped<IXService, XService>();
services.AddHostedService<MyHostedService>();
Run Code Online (Sandbox Code Playgroud)
我在DbContext中遇到了类似的问题,我通过/sf/answers/3385825411/解决了这个问题,但是这次我需要通过更深层次的依赖注入并在每个服务中处理IServiceScopeFactory优雅的解决方案。
c# dependency-injection asp.net-core asp.net-core-hosted-services
我有一个托管服务,每分钟检查一个电子邮件帐户。我也将 MVC 与 Web API 2.1 一起使用。为了让我的托管服务启动,我必须通过调用 API 方法来“唤醒它”。在 Web API 不活动一段时间后,托管服务进入睡眠状态并停止检查电子邮件。就像它正在收集垃圾一样。如何让它持续运行?
将不胜感激。
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info {Title = "CAS API", Version = "v1"});
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
})
.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins(Configuration["uiOrigin"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
})
.AddHostedService<EmailReceiverHostedService>()
.Configure<EmailSettings>(Configuration.GetSection("IncomingMailSettings"))
.AddSingleton<IEmailProcessor, MailKitProcessor>()
.AddSingleton<IEmailRepository, EmailRepository>()
...
Run Code Online (Sandbox Code Playgroud)
EmailReceiverHostedService.cs:
using CasEmailProcessor.Options;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using …Run Code Online (Sandbox Code Playgroud) asp.net-core asp.net-core-webapi asp.net-core-2.1 asp.net-core-hosted-services
我似乎在这个问题上找不到太多。我遇到的问题是我需要运行 2 个以上长时间运行的后台服务,但只有第一个注册服务的 ExecuteAsync 被执行。我尝试通过BackgroundService 实现它并将代码放入ExecuteAsync,并且我尝试直接实现IHostedService 并将长时间运行的代码放入StartAsync。
我认为问题是 return Task.CompletedTask; 从未被调用过。例如,我有两个作为 BackgroundServices 实现的 Kafka 消费者,除了主题和 OnMessage 方法之外,代码看起来相同
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
var kafkaEndpoint = _kafkaConfig.Endpoint;
var kafkaTopic = "PhoenixEventStore";
var consumerConfig = new Dictionary<string, object>
{
{ "group.id", "consumer1" },
{ "bootstrap.servers", kafkaEndpoint },
{ "auto.offset.reset", "earliest" }
};
using (var consumer = new Consumer<Null, string>(consumerConfig, null, new StringDeserializer(Encoding.UTF8)))
{
consumer.OnMessage += (obj, msg) =>
{
Log.Information($"Consumer1 Received {msg.Value}");
};
consumer.OnPartitionEOF += (_, end) =>
{
Log.Information($"Consumer1 Reached …Run Code Online (Sandbox Code Playgroud) multiple-instances background-service asp.net-core asp.net-core-hosted-services
我有一个在 .net core 2.0 启动时启动的后台任务,从 backgroundservice 继承,实现了 StartAsync、StopAsync 和 ExecuteAsync。这个任务是根据一些业务逻辑定期更新数据库表中的一些数据。
虽然我可以将后台任务作为应用程序运行并使用日志、数据库检查和其他工具的帮助进行测试,但单元测试是否是测试后台任务所必需的?如果是这样,如何将任务注册为具有依赖项的服务并触发 start 和 stop 方法来断言实际与预期?欣赏一些基本的示例单元测试方法,用于测试基于 .net 核心 ihostedservice 后台任务的计时器。
这是我的基本测试开始,仅用于示例,但尚未完成。话虽如此,这只是一个想法,而不是确切的工作测试。这是需要社区帮助的地方。还可以添加更多断言,即 Assert.Verify()?
[Fact]
public async void Run_background_task_success()
{
//Arrange
IServiceCollection services = new ServiceCollection();
services.AddHostedService<BackgroundManagerTask>();
var serviceProvider = services.BuildServiceProvider();
var service = serviceProvider.GetService<IHostedService>() as BackgroundManagerTask;
var isExecuted = false;
if(await service.StartAsync(CancellationToken.None))
{
isExecuted = true;
}
await Task.Delay(10000);
Assert.True(isExecuted);
await service.StopAsync(CancellationToken.None);
}
Run Code Online (Sandbox Code Playgroud) unit-testing background-process microservices asp.net-core-hosted-services
我正在我的 ASP.NET Core 网站中实现定时后台服务,使用在此博客文章中找到的代码作为模型。执行实际工作的部分如下所示...
protected async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// Put your code here
// Wait 30 minutes before running again.
await Task.Delay(TimeSpan.FromMinutes(30), stoppingToken);
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,直到某些原因导致服务崩溃。显然,在生产应用程序中,您希望这不会发生,但实际上,我需要考虑这种可能性。
据我所知,框架创建并启动了任务,应用程序的其余部分对此一无所知。我可以检测IHostedService服务是否崩溃,我可以重新启动它吗?如果没有,我该怎么办?定期运行此程序对网站至关重要,因此我需要知道我可以处理任何问题。
回到 .net core 2,我创建了一个带有自定义属性的托管服务,例如:
public class MyService : BackgroundService
{
public bool IsRunning {get;set;}
...
Run Code Online (Sandbox Code Playgroud)
我可以在 startup.cs 中设置,如:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHostedService,HostedServices.MyService>();
...
Run Code Online (Sandbox Code Playgroud)
然后我可以在剃刀页面的其他地方引用它,例如:
public class IndexModel : PageModel
{
private readonly IHostedService _mySrv;
public IndexModel(IHostedService mySrv) => _mySrv = mySrv;
[BindProperty]
public bool IsRunning { get; set; }
public void OnGet() => IsRunning = ((HostedServices.MyService)_mySrv).IsRunning;
}
Run Code Online (Sandbox Code Playgroud)
现在我已升级到 .net core 3,我的启动已更改为:
services.AddHostedService<HostedServices.MyService>();
Run Code Online (Sandbox Code Playgroud)
但是我在 IndexModel 中的 DI 引用不再为我提供 MyService,而是为我提供了一个 GenericWebHostService 类型的对象,我无法弄清楚如何从中获取我的自定义 MyService。在 IndexModel 中将“IHostedService”更改为“MyService”也不起作用,我收到“无法解析服务”错误。
如何从依赖注入中取回 MyService 的实例?
c# asp.net-core asp.net-core-hosted-services asp.net-core-3.0
Azure 函数与ASP.NET Core Worker Service有何不同?
这两者是否涵盖相同的用例?我如何决定使用哪一个?
用户可以通过向 ASP.NET Core 控制器发送请求来触发长时间运行的作业。当前,控制器执行作业,然后发送 200 OK 响应。问题是客户端必须等待相当长的时间才能得到响应。
这就是我目前尝试在后台任务中处理作业的原因。我正在使用一个IBackgroundTaskQueue存储所有作业的地方,并且IHostedService在有新作业入队时处理作业。它类似于Microsoft 文档中的代码。
但该作业确实需要访问数据库,因此用户必须使用 Active Directory 进行身份验证。因此,我需要访问HttpContext.User后台任务中的属性。不幸的是,在HttpContext发送响应时和作业处理开始之前,它会被处理掉。
public class Job
{
public Job(string message)
{
Message = message;
}
public string Message { get; }
}
Run Code Online (Sandbox Code Playgroud)
控制器将新作业排入任务队列。
[HttpGet]
public IActionResult EnqueueJob()
{
var job = new Job("Hello World");
this.taskQueue.QueueBackgroundWorkItem(job);
return Accepted();
}
Run Code Online (Sandbox Code Playgroud)
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private ConcurrentQueue<Job> jobs = new ConcurrentQueue<Job>();
private SemaphoreSlim signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Job …Run Code Online (Sandbox Code Playgroud) 我有一个 ASP .NET core Web API,它使用此处描述的排队后台任务 。
我已使用提供的代码示例并添加了IBackgroundTaskQueue,BackgroundTaskQueue和 ,QueuedHostedService完全按照文章中所述。
在 my 中Startup.cs,我仅注册一个QueuedHostedService实例,如下所示:services.AddHostedService<QueuedHostedService>();
来自 WebApi 控制器的任务将被入队,然后出队并由QueuedHostedService.
我希望允许多个后台处理线程使传入的任务出队并执行。我能想到的最直接的解决方案是QueuedHostedService在我的Startup.cs. 即,像这样:
int maxNumOfParallelOperations;
var isValid = int.TryParse(Configuration["App:MaxNumOfParallelOperations"], out maxNumOfParallelOperations);
maxNumOfParallelOperations = isValid && maxNumOfParallelOperations > 0 ? maxNumOfParallelOperations : 2;
for (int index = 0; index < maxNumOfParallelOperations; index++)
{
services.AddHostedService<QueuedHostedService>();
}
Run Code Online (Sandbox Code Playgroud)
我还注意到,由于 中的信号量BackgroundTaskQueue,QueuedHostedService实例并不是一直在工作,而是仅在队列中有新任务可用时才唤醒。
这个解决方案在我的测试中似乎效果很好。
但是,在这个特定的用例中 - 它真的是一个有效的、推荐的并行处理解决方案吗?
c# asp.net parallel-processing asp.net-core asp.net-core-hosted-services
在 .Net 5 Web API 中,我想运行一个发送批量电子邮件和 SMS 的后台任务。我知道我可以创建一个从 BackgroundService 继承的服务,然后将它添加到 Startup.ConfigureServices 方法中的 DI 容器,如下所示:
services.AddHostedService<EmailAndSmsService>();
Run Code Online (Sandbox Code Playgroud)
但这会立即运行服务 - 即在应用程序启动时。我想在 API 收到来自前端的请求时运行该服务。即在控制器的动作方法中。
我一直在查看 Microsoft 文档中的“带有托管服务的后台任务”,如果我没记错的话,这就是我需要做的(查看标题为“在后台任务中使用范围服务”的部分):
这样对吗?我是否基本上需要创建两个服务,一个执行实际工作,另一个调用执行实际工作的服务?我在正确的道路上吗?
谢谢
c# background-service .net-core asp.net-core asp.net-core-hosted-services
asp.net-core-hosted-services ×10
asp.net-core ×8
c# ×6
.net-core ×1
asp.net ×1
azure ×1
unit-testing ×1