我无法弄清楚如何访问我的ConsoleHostedService实现类中的命令行参数。我在源代码中看到CreateDefaultBuilder(args)以某种方式将其添加到配置中...名为Args...
有主程序:
internal sealed class Program
{
private static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
.UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.ConfigureServices((context, services) =>
{
services.AddHostedService<ConsoleHostedService>();
})
.RunConsoleAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
和托管服务:
internal sealed class ConsoleHostedService : IHostedService
{
public ConsoleHostedService(
IHostApplicationLifetime appLifetime,
IServiceProvider serviceProvider)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud) 我一直在研究 .NET 通用主机用于托管控制台应用程序的用途。与 ASP.NET Web 应用程序相比,这似乎是 .NET 的推荐模式,允许轻松使用 DI、日志记录、配置等,同时保持一致的 API。当我遇到这个例子时,我开始有点理解了来说明 IHostApplicationLifetime 事件的使用
\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.Extensions.Logging;\n\nnamespace AppLifetime.Example;\n\npublic class ExampleHostedService : IHostedService\n{\n private readonly ILogger _logger;\n\n public ExampleHostedService(\n ILogger<ExampleHostedService> logger,\n IHostApplicationLifetime appLifetime)\n {\n _logger = logger;\n\n appLifetime.ApplicationStarted.Register(OnStarted);\n appLifetime.ApplicationStopping.Register(OnStopping);\n appLifetime.ApplicationStopped.Register(OnStopped);\n }\n\n public Task StartAsync(CancellationToken cancellationToken)\n {\n _logger.LogInformation("1. StartAsync has been called.");\n\n return Task.CompletedTask;\n }\n\n public Task StopAsync(CancellationToken cancellationToken)\n {\n _logger.LogInformation("4. StopAsync has been called.");\n\n return Task.CompletedTask;\n }\n\n private void OnStarted()\n {\n _logger.LogInformation("2. OnStarted has been called.");\n }\n\n private void …Run Code Online (Sandbox Code Playgroud) 我知道在Asp.Net 3.0(或3.1)之前,要手动启动BackgroundService,我们可以从中派生它IHostedService并将DI注册更改为:
services.AddSingleton<IHostedService, CustomHostedService>();
Run Code Online (Sandbox Code Playgroud)
然后通过在构造函数中注入服务并调用 来手动触发服务启动StartAsync()。
但是,我似乎无法在 Asp.Net Core 3.1 中做到这一点。看一下该StartAsync()方法的代码,后台服务是在应用程序启动完成之前启动的。
public async Task StartAsync(CancellationToken cancellationToken = default)
{
_logger.Starting();
await _hostLifetime.WaitForStartAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
_hostedServices = Services.GetService<IEnumerable<IHostedService>>();
foreach (var hostedService in _hostedServices)
{
// Fire IHostedService.Start
await hostedService.StartAsync(cancellationToken).ConfigureAwait(false);
}
// Fire IApplicationLifetime.Started
_applicationLifetime?.NotifyStarted();
_logger.Started();
}
Run Code Online (Sandbox Code Playgroud)
手动触发后台服务启动的最佳方法是什么?
本质上,这是我的设置:
后台服务
public MyBackgroundService(Func<string, IConsumer> consumerFactory)
{
_consumerFactory = consumerFactory ?? throw new ArgumentNullException(nameof(consumerFactory));
}
Run Code Online (Sandbox Code Playgroud)
消费者工厂注册
services.AddSingleton<Func<string, IConsumer>>(provider => providerName => provider.ConfigureConsumer(environment, providerName));
private static IConsumer ConfigureConsumer(this IServiceProvider provider, …Run Code Online (Sandbox Code Playgroud) 我有一个 API,其中包含一个使用 .Net 6 在 VS2022 中构建的 HostedService。
当我在本地运行时,该服务将按预期调用,并且一切正常,但部署后,该服务似乎无法启动。
我尝试了许多不同的配置,甚至尝试使用后台服务,但结果都是相同的。这是我的代码:
我有一个在 VS2019 .Net Core 3.1 中构建的现有应用程序,它有一个 HostedService 并且工作正常。我注意到,当我将 .Net Core 应用程序转换为 .Net 6 时,该服务在部署时并未启动,因此我决定构建一个小应用程序来尝试找出导致问题的原因。
程序.cs
using HostedServices.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((context, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(context.Configuration)
.Enrich.FromLogContext()
.Enrich.WithMachineName());
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddHostedService<MainService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Run Code Online (Sandbox Code Playgroud)
这是托管服务
namespace HostedServices.Services
{
public class MainService : IHostedService, IDisposable
{
private int executionCount = 0;
private readonly ILogger<MainService> _logger; …Run Code Online (Sandbox Code Playgroud) 在 ASP.NET Core 上,我观察到一种奇怪的行为,这实际上是在BackgroundService 中报告的,未关闭,stoppingToken 从未使用 .net core 通用主机设置,但从未找到根本原因
我正在创建以下BackgroundService任务,注册为HostedService:
唯一的方法是这样实现的:
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested )
Console.WriteLine("running");
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试Ctrl+C或杀死-15这个,它不会停止。
如果我像这样更改函数:
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested )
{
Console.WriteLine("running");
await Task.Delay(1);
}
}
Run Code Online (Sandbox Code Playgroud)
这是有效的:如果我尝试Ctrl+C该程序,则会设置取消令牌,然后退出。
如果我返回到不起作用的版本并暂停它,我会看到即使我处于 ExecuteAsync 方法中,它下面的框架也是 StartAsync(),在这种情况下它永远不会完成!
我看到的 StartAsync() 代码(来自框架)是这样的:
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token); …Run Code Online (Sandbox Code Playgroud) c# background-service async-await asp.net-core ihostedservice
我有一个应用程序,通常应该是一个简单的控制台应用程序,可以编程为 Windows 任务计划程序不时调用的计划任务。
\n该程序应该在两个数据库上启动一些更新,每个数据库一项服务。说ContosoDatabase应该更新ContosoService。
最后,它被编写为一个 .NET Core 应用程序,使用s作为服务的基础,这也许不是最好的选择,如下所示:IHostedService
public class ContosoService : IHostedService {\n private readonly ILogger<ContosoService> _log;\n private readonly IContosoRepository _repository;\n \n private Task executingTask;\n\n public ContosoService(\n ILogger<ContosoService> log,\n IContosoRepository repository,\n string mode) {\n _log = log;\n _repository = repository;\n }\n\n public Task StartAsync(CancellationToken cancellationToken) {\n _log.LogInformation(">>> {serviceName} started <<<", nameof(ContosoService));\n executingTask = ExcecuteAsync(cancellationToken);\n\n // If the task is completed then return it, \n // this should bubble cancellation and …Run Code Online (Sandbox Code Playgroud) background-process .net-core asp.net-core-hosted-services .net-5 ihostedservice
在 WPF 应用程序中,我配置了一个托管服务来在后台执行特定活动(参见本文)。这是在 App.xaml.cs 中配置托管服务的方式。
public App()
{
var environmentName = Environment.GetEnvironmentVariable("HEALTHBOOSTER_ENVIRONMENT") ?? "Development";
IConfigurationRoot configuration = SetupConfiguration(environmentName);
ConfigureLogger(configuration);
_host = Host.CreateDefaultBuilder()
.UseSerilog()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>()
.AddOptions()
.AddSingleton<IMailSender, MailSender>()
.AddSingleton<ITimeTracker, TimeTracker>()
.AddSingleton<NotificationViewModel, NotificationViewModel>()
.AddTransient<NotificationWindow, NotificationWindow>()
.Configure<AppSettings>(configuration.GetSection("AppSettings"));
}).Build();
AssemblyLoadContext.Default.Unloading += Default_Unloading;
Console.CancelKeyPress += Console_CancelKeyPress;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
Run Code Online (Sandbox Code Playgroud)
并开始启动
/// <summary>
/// Handles statup event
/// </summary>
/// <param name="e"></param>
protected override async void OnStartup(StartupEventArgs e)
{
try
{
Log.Debug("Starting the application");
await _host.StartAsync(_cancellationTokenSource.Token);
base.OnStartup(e);
}
catch …Run Code Online (Sandbox Code Playgroud) 我正在使用 .Net Core 后台服务连接到 Kafka 并将消息保存到 SQL Server。我的项目结构如下所示:

Entity Framework在基础设施依赖项中,我使用IConfiguration configuration从 WorkerProgram.cs文件传递的以下代码进行注册services.AddInfrastructure(configuration):
namespace JS.Svf.BackgroundServices.Infrastructure
{
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
// Add all the dependencies required by Azure Functions.
// From Infrastructure
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));
services.AddTransient<IApplicationDbContext>(provider => provider.GetRequiredService<ApplicationDbContext>());
services.AddTransient<IProductRepository, ProductRepository>();
services.AddTransient<ISupplierRepository, SupplierRepository>();
return services;
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行后台服务后出现以下错误:
Cannot consume scoped service 'ApplicationDbContext' from singleton 'Microsoft.Extensions.Hosting.IHostedService'
通过参考,我知道我们需要使用IServiceScopeFactory,但我对如何在当前结构中使用它有点无能为力。请指教。
该存储库使用ApplicationDbContext …
如何属性注册一个包含IHostedService和自定义接口(如 )的类IMyInterface?
如在
class BackgroundTaskScheduler : BackgroundService, ITaskScheduler {...}
如果配置如下:
services.AddHostedService<BackgroundTaskScheduler>();
Run Code Online (Sandbox Code Playgroud)
然后尝试将其注入客户端,如下所示:
public class Foo
{
Foo(ITaskScheduler taskScheduler) {...}
}
Run Code Online (Sandbox Code Playgroud)
生成错误,指出 ASP.net 无法解析BackgroundTaskScheduler,为什么?
c# ×6
.net-core ×4
.net ×3
asp.net-core ×3
asp.net-core-hosted-services ×2
.net-5 ×1
.net-6.0 ×1
async-await ×1
task ×1
wpf ×1