标签: asp.net-core-hosted-services

.NET 通用主机:防止应用程序因未处理的异常而崩溃

我有一个 .NET 通用主机,IHostedService它从 OPC-UA 接口接收事件并处理它们。

问题是,如果在处理事件的过程中出现未处理的异常,整个应用程序就会崩溃

我阅读了文档,但没有找到关于全局异常处理程序或允许捕获未处理异常并防止应用程序崩溃的类似机制的任何信息。

是否有保护通用主机以及IHostedService防止未处理异常的解决方案?

编辑

我知道,这里最简单的事情是尝试/捕获异常而不是让它冒泡。但是我想知道是否有类似 WinForms / WPF 的机制,您可以在其中更全局地捕获此类异常并防止崩溃。

编辑

这是代码的简化版本:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        return new HostBuilder()
            .UseEnvironment(environmentName)
            .ConfigureLogging((hostContext, logging) =>
            {
                ...
            })
            .ConfigureAppConfiguration((hostContext, builder) =>
            {
                builder
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", true, true)
                    .AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", true, true)
                    .AddEnvironmentVariables();
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<IHostedService, OpcClientHostedService>();
                ...
            });
    }
}

public class OpcClientHostedService : …
Run Code Online (Sandbox Code Playgroud)

c# .net-core asp.net-core asp.net-core-hosted-services

9
推荐指数
1
解决办法
3517
查看次数

优雅地停止 ASP.NET Core Web App(从 Visual Studio 调试器中),一个与 IHostedService 相关的问题

我对 ASP.NET Core 完全陌生,所以我可能在 50 英里之外遗漏了一些东西,因为我在这上面花了 3 个小时无济于事。

我在 VS 2017 中制作了一个 Web 应用程序,由 Kestrel 托管,它在 IIS Express 下运行(当你创建一个新的 Web 应用程序时,这是所有默认设置)。当我按 F5 时,应用程序启动,我的 Chrome 浏览器打开,我看到“hello world”式的输出。当我关闭此浏览器窗口时,应用程序终止。

现在,我需要在后台执行一些任务,并且需要这些任务具有清理逻辑 - 我发现这IHostedService允许我执行此操作。

该文件指出:

当您注册 IHostedService 时,.NET Core 将分别在应用程序启动和停止期间调用 IHostedService 类型的 StartAsync() 和 StopAsync() 方法。

我已经做好了:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHostedService<MyBackgroundService>();
}
Run Code Online (Sandbox Code Playgroud)

服务按预期启动,一切正常。极其简单的东西。但它永远不会停止,至少不会优雅地停止。

当我关闭那个自动启动的浏览器窗口时,我的应用程序也随之关闭,但是我的IHostedService服务中的这个方法:

public Task StopAsync(CancellationToken cancellationToken)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

永远不会被调用。

我已经尝试了文档中提供示例,它显示了相同的问题 - 在 VS 中尝试时从未完成清理。

我注意到来自名为“ASP.NET Core Web Server”的输出通道的特殊信息:

public void …
Run Code Online (Sandbox Code Playgroud)

c# visual-studio-2017 asp.net-core-2.1 asp.net-core-hosted-services

8
推荐指数
2
解决办法
2596
查看次数

如何在没有http请求的MVC Core应用程序中启动HostedService

在我的MVC .NET核心2.2应用程序中,有HostedService进行后台工作.

它是在Startap类的ConfigureServices方法中注册的

services.AddHostedService<Engines.KontolerTimer>();
Run Code Online (Sandbox Code Playgroud)

由于这是独立于用户请求的后台服务,因此我想在应用启动时立即启动后台服务.现在是我的HostedService在第一次用户请求后盯着的情况.

在MVC Core应用程序启动时启动HostedService的正确方法是什么

我的服务看起来像这个https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2

internal class TimedHostedService : IHostedService, IDisposable
{
    private readonly ILogger _logger;
    private Timer _timer;

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        _logger.LogInformation("Timed Background Service is working.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose() …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-core asp.net-core-hosted-services

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

何时应将AllowSynchronousContinuations 选项与通道一起使用?

我正在 Asp Net Core 应用程序中实现简单的后台作业队列。我创建了它在幕后BackgroundJobQueue使用来排队将通过 处理的项目。阅读文档我偶然发现了通道的ChannelOptions.AllowSynchronousContinuations设置。BoundedChannel<T>HostedService

根据msdn的描述说:

将此选项设置为 true 可以通过避免安排额外的工作项目来提供可测量的吞吐量改进。然而,这可能会以减少并行性为代价,例如生产者可能是执行与消费者相关的工作的人,如果不深思熟虑,这可能会导致意外的交互。默认为 false。

我不太明白true在我的情况下设置此选项是否是一个好的选择。有人可以解释+提供这个选项何时有用/无用/有害的例子吗?

编辑

我得到的解释:

根据官方的说法,当生产者依赖于消费者时,它会等待消费者的工作完成然后开始工作,如果启用该选项,生产者会经历更多的空闲时间。但是,如果禁用该选项,由于并行性,生产者的空闲时间会减少。

启用选项不是很糟糕吗?由于 api 请求将需要更长的时间来处理,因为生产者将保持空闲的时间更长。为了澄清我的意思。假设我想在我的控制器中排队后台作业

public async Task<IActionResult> Action()
{
    // some code
   await _backgroundJobQueue(() => ....);
   return Ok();
}
Run Code Online (Sandbox Code Playgroud)

如果启用选项,那么生产者会经历更多的空闲时间,因此执行操作需要更长的时间?

c# asp.net-core asp.net-core-hosted-services

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

.NET Core 中的单元测试托管服务

我有一个由 .NET Core 中的托管服务实现的后台任务。这个类中的逻辑很少:

public class IndexingService : IHostedService, IDisposable
{
    private readonly int indexingFrequency;

    private readonly IIndexService indexService;

    private readonly ILogger logger;

    private bool isRunning;

    private Timer timer;

    public IndexingService(ILogger<IndexingService> logger, IIndexService indexService, IndexingSettings indexingSettings)
    {
        this.logger = logger;
        this.indexService = indexService;

        this.indexingFrequency = indexingSettings.IndexingFrequency;
    }

    public void Dispose()
    {
        this.timer?.Dispose();
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        this.timer = new Timer(this.DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(this.indexingFrequency));
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        this.timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    private …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing .net-core asp.net-core-hosted-services

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

如何将数据从控制器传递到后台服务

我正在尝试编写一个简单的 Web api 项目,其中后台服务每秒执行一个方法。此方法循环遍历列表并仅打印(暂时)一些统计信息。我在后台服务的构造函数中声明了一个新列表。

我目前在从控制器内部添加和删除项目时遇到一些问题。

public UsersController(IUserBackgroundService userService)
{
   private readonly IUserBackgroundService _userService;

   public UserController(IUserBackgroundService userService)
   {
       _userService = userservice;
   }

   [HttpPost]
   public IActionResult PostUser(User user)
   {
      _userService.Add(user) 
   }
}

public UserService: BackgroundService, IUserService
{
    private List<User> Users;

    public UserService()
    {
       Users = new List<Users>();
    }
    protected override ExecuteAsync(CancellationToken token)
    {
        //this will execute the GenerateUserStats every second
    }

    //this method is being executed every second 
    protected Task GenerateUserStatistics()
    {
        Console.WriteLine($"Nr. of users {users.count}");
        foreach(var user in users)
        {
            Console.WriteLine($"{user.fname} …
Run Code Online (Sandbox Code Playgroud)

c# background-service asp.net-core asp.net-core-webapi asp.net-core-hosted-services

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

仅在横向扩展的 Azure 应用服务的一个实例上运行 IHostedService

是否可以IHostedService在 ASP.NET Core 中仅在一个横向扩展的 Azure 应用服务实例上运行?IHostedService或者解决方案是在一个实例的自己的应用程序服务中运行它?

我有一个BackgroundService每天运行一次并通过电子邮件发送报告的程序。当我的应用服务扩展到 2 个实例时,该服务将每天同时运行两次,从而导致发送两封相同的电子邮件。

我怎么解决这个问题?

autoscaling azure-web-app-service asp.net-core asp.net-core-hosted-services

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

在 Configure() 之后启动 IHostedService

我有一个 .NET Core 3.1 应用程序,它提供一个描述应用程序运行状况的端点,以及一个处理数据库中数据的 IHostedService。但是有一个问题,HostedService 的 worker 函数开始处理很长时间,导致Configure()Startup 中的方法没有被调用,/status端点没有运行。

我希望/status端点在 HostedService 启动之前开始运行。如何在托管服务之前启动端点?

示例代码

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<SomeHostedProcessDoingHeavyWork>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/status", async context =>
            {
                await context.Response.WriteAsync("OK");
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

托管服务

public class SomeHostedProcessDoingHeavyWork : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            await MethodThatRunsForSeveralMinutes();
            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); …
Run Code Online (Sandbox Code Playgroud)

c# .net-core asp.net-core asp.net-core-hosted-services

6
推荐指数
2
解决办法
2419
查看次数

有没有办法在下载客户端 Blazor 应用程序之前对用户进行身份验证?

我目前正在开发一个核心托管的 Blazor Web 程序集项目。该项目分为三个部分:客户端、服务器和共享。我的理解是,当用户点击网址时,他们将下载客户端包并在网络浏览器上运行它。我想知道是否有办法在用户下载客户端包之前对用户进行身份验证?

我已使用 microsoft 文档在客户端成功实现了登录过程: 使用 Azure Active Directory 确保 ASP.NET Core Blazor WebAssembly 托管应用程序的安全

但我想更进一步,看看在下载客户端包之前是否可以对用户进行身份验证。

我花了大部分时间向 Server.Startup.cs 添加身份验证代码,假设当用户导航到我的网站时,他们会向服务器请求客户端包。

有没有人尝试过做这样的事情?感谢您的任何建议

azure-active-directory blazor asp.net-core-hosted-services blazor-server-side blazor-webassembly

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

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
查看次数