我一起使用 AddSingleton 和 AddHostedService 在后端有一個長期運行的服務(BackgroundService),而控制器訪問相同的服務來獲取資料。以下是我的發現:
- 如果同時使用 AddSingleton 和 AddHostedService,BackgroundService 將被初始化兩次(不是 Singleton)。控制器只能訪問在 AddSingleton 中創建的那個。
除錯輸出(建構式呼叫兩次,查看秒數差異)
BGService 建構式服務 addGame:games 計數為 1 BGService 建構式服務 addGame:games 計數為 1 ExecuteAsync 1 :games 計數為 1:[ "CONSTRUCTOR GAME AT 10/29/2021 10:37:25 AM(0)" ] ... ... ExecuteAsync 7 :games count is 1:[ "CONSTRUCTOR GAME AT 10/29/2021 10:37:25 AM(0)" ] service addGame:games count is 2 After AddGame: [
"CONSTRUCTOR GAME AT 10/29/2021 " /2021 10:37:24 AM(0)", "游戲 0(1)" ]
如果只使用 AddSingleton,它會起作用。
如果僅使用 AddHostedService,則 BackgroundService 正在運行,但 DI 在控制器中不起作用(例外)。
**> 失敗:
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware 1 執行請求時發生未處理的例外。System.InvalidOperationException:嘗試激活“CoreServiceSignalRSample.Controllers.WeatherForecastController”時無法決議“CoreServiceSignalRSample.service.IBGService”型別的服務。
在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
在 lambda_method(Closure , IServiceProvider , Object[] )**
我的問題是,DI BackgroundService 的正確方法是什么,為什么推薦 AddHostedService?
示例代碼可以在https://github.com/huangpat/CoreServiceSignalRSample找到。
Startup.cs 配置服務
services.AddSingleton<IBGService>(new BGService());
services.AddHostedService<BGService>();
BG服務
private List<string> games;
public BGService()
{
Console.WriteLine("BGService constructor");
this.games = new List<string>();
this.addGame("Constructor Game at " DateTime.Now.ToString());
}
public async Task<bool> addGame(string fGame)
{
if (this.games.Count <= 20)
{
this.games.Add(fGame.ToUpper() "(" Convert.ToString(this.games.Count) ")");
Console.WriteLine("service addGame:games count is " Convert.ToString(this.games.Count));
return true;
}
else
{
return false;
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
int i = 0;
while (true)
{
i ;
if (games.Count == 0)
{
this.addGame("ExecuteAsync Game at " DateTime.Now.ToString());
}
JsonSerializer js = new JsonSerializer();
Console.WriteLine("ExecuteAsync {1} :games count is {0}:{2}", this.games.Count, i, JsonConvert.SerializeObject(this.games, Formatting.Indented));
await Task.Delay(1000 * 2 * 5);
}
//throw new NotImplementedException();
/
/ 使用執行緒池啟動集合中的每個游戲 }
uj5u.com熱心網友回復:
每個注冊都將創建自己的型別描述符,并使用自己的決議規則(即默認情況下它將使用相應的建構式)。您可以使用注冊實作工廠來解決它:
services.AddSingleton<BGService>();
services.AddSingleton<IBGService>(provider => provider.GetRequiredService<BGService>());
services.AddHostedService<BGService>(provider => provider.GetRequiredService<BGService>())
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/344060.html
上一篇:過濾LINQ運算式中的物件-C#
