Jam*_*mes 5 c# asp.net-core asp.net-core-2.0
我正在尝试使用IHostedService创建后台服务.如果我只有一个后台服务,一切正常.当我尝试创建多个实现时,IHostedService只有第一个实际运行的实现.
services.AddSingleton<IHostedService, HostedServiceOne>();
services.AddSingleton<IHostedService, HostedServiceTwo>();
Run Code Online (Sandbox Code Playgroud)
在上面的例子StartAsync上HostedServiceOne被调用,但StartAsync上HostedServiceTwo不会被调用.如果我换登记的两种实现方式的顺序IHostedService(把IHostedServiceTwo前IHostedServiceOne),然后StartAsync在HostedServiceTwo被调用而从来不是HostedServiceOne.
编辑:
我被引导到以下内容:
然而,这不适合IHostedService.要使用建议的方法,我将不得不打电话,serviceProvider.GetServices<IService>();但似乎IHostedService.StartAsync似乎在内部调用.我甚至不确定我会在哪里触发它IHostedService.StartAsync.
小智 7
我有同样的问题。必须在每个服务中返回Task.CompletedTask;
public class MyHostedService: IHostedService
{
public Task StartAsync(CancellationToken cancellationToken)
{
Task.Run(() => SomeInfinityProcess(cancellationToken));
return Task.CompletedTask;
}
public void SomeInfinityProcess(CancellationToken cancellationToken)
{
for (; ; )
{
Thread.Sleep(1000);
if (cancellationToken.IsCancellationRequested)
break;
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
Startup.cs是相同的:
services.AddHostedService<MyHostedService>();
services.AddHostedService<MyHostedService2>();
...
Run Code Online (Sandbox Code Playgroud)
注册HostedService如下:
// services.AddSingleton<IHostedService, HostedServiceOne>();
// services.AddSingleton<IHostedService, HostedServiceTwo>();
services.AddHostedService<HostedServiceOne>();
services.AddHostedService<HostedServiceTwo>();
Run Code Online (Sandbox Code Playgroud)
它将按预期工作.
这似乎可以通过装饰来解决IHostedService,尽管.Net Core的默认IoC容器不支持注册装饰器,但有一个简单的解决方法。
您可以像这样创建一个装饰器IHostedService:
public abstract class MyHostedServiceDecorator : IHostedService
{
private readonly MyHostedServiceDecorator _next;
protected MyHostedServiceDecorator(MyHostedServiceDecorator next)
{
_next = next;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
await StartAsyncInternal(cancellationToken);
if (_next != null)
{
await _next.StartAsync(cancellationToken);
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await StopAsyncInternal(cancellationToken);
if (_next != null)
{
await _next.StopAsync(cancellationToken);
}
}
protected abstract Task StartAsyncInternal(CancellationToken token);
protected abstract Task StopAsyncInternal(CancellationToken token);
}
Run Code Online (Sandbox Code Playgroud)
创建您需要的尽可能多的装饰器,例如:
public class HostedServiceOneDecorator : MyHostedServiceDecorator
{
public HostedServiceOneDecorator(MyHostedServiceDecorator next) : base(next)
{
}
protected override async Task StartAsyncInternal(CancellationToken token)
{
Console.Write("This is my decorated start async!");
}
protected override async Task StopAsyncInternal(CancellationToken token)
{
Console.Write("This is my decorated stop async!");
}
}
Run Code Online (Sandbox Code Playgroud)
在您注册的托管服务中,像这样调用装饰器:
public class MyHostedService : IHostedService
{
private readonly MyHostedServiceDecorator
_decorator;
public MyHostedService(MyHostedServiceDecorator decorator)
{
_decorator = decorator;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
// base StartAsync logic ...
await _decorator.StartAsync(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// base StopAsync logic ...
await _decorator.StopAsync(cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,通过在前一个构造函数中传递下一个装饰器来注册服务及其装饰器。
services.AddSingleton<IHostedService, MyHostedService>();
services.AddSingleton<MyHostedServiceDecorator>(
new HostedServiceOneDecorator(new HostedServiceTwoDecorator(/*etc*/)));
Run Code Online (Sandbox Code Playgroud)
所有的装饰器都会以链式的方式被调用,直到没有下一个!
| 归档时间: |
|
| 查看次数: |
3361 次 |
| 最近记录: |