标签: ihostedservice

如何使用 IHostedService 访问控制台应用程序中的命令行参数?

我无法弄清楚如何访问我的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 console-application .net-core ihostedservice

7
推荐指数
1
解决办法
3264
查看次数

何时应使用 IHostApplicationLifetime.OnStarted 事件与 IHostedService.StartAsync?

我一直在研究 .NET 通用主机用于托管控制台应用程序的用途。与 ASP.NET Web 应用程序相比,这似乎是 .NET 的推荐模式,允许轻松使用 DI、日志记录、配置等,同时保持一致的 API。当我遇到这个例子时,我开始有点理解了来说明 IHostApplicationLifetime 事件的使用

\n
using 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)

.net c# ihostedservice

7
推荐指数
0
解决办法
1248
查看次数

有没有办法在Asp.Net core 3.1中手动启动BackgroundService

我知道在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)

c# asp.net-core asp.net-core-3.1 ihostedservice

6
推荐指数
1
解决办法
1万
查看次数

IHostedService .NET 6 部署时未启动

我有一个 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-hosted-services ihostedservice .net-6.0

6
推荐指数
1
解决办法
6739
查看次数

如果没有等待完成,BackgroundService 永远不会启动/停止

在 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

5
推荐指数
1
解决办法
1498
查看次数

重写 IHostedService 以在所有任务完成后停止

我有一个应用程序,通常应该是一个简单的控制台应用程序,可以编程为 Windows 任务计划程序不时调用的计划任务。

\n

该程序应该在两个数据库上启动一些更新,每个数据库一项服务。说ContosoDatabase应该更新ContosoService

\n

最后,它被编写为一个 .NET Core 应用程序,使用s作为服务的基础,这也许不是最好的选择,如下所示:IHostedService

\n
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

4
推荐指数
1
解决办法
4575
查看次数

如何停止和恢复worker服务?

在 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)

c# wpf task .net-core ihostedservice

3
推荐指数
1
解决办法
1万
查看次数

无法使用单例“Microsoft.Extensions.Hosting.IHostedService”中的作用域服务“ApplicationDbContext”

我正在使用 .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 …

c# entity-framework-core .net-core ihostedservice

2
推荐指数
1
解决办法
3749
查看次数

Asp.net core 如何注册 IHostedService(也包含自定义接口)

如何属性注册一个包含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,为什么?

.net c# asp.net-core ihostedservice

0
推荐指数
1
解决办法
1517
查看次数