.NET Generic Host: предотвращение сбоя приложения при необработанном исключении

У меня есть.NET Generic Host с IHostedService который получает события от интерфейса OPC-UA и обрабатывает их.

Проблема в том, что если во время обработки события возникает необработанное исключение, происходит сбой всего приложения

Я прочитал документацию, но не нашел ничего о глобальном обработчике исключений или подобном механизме, который позволяет перехватывать необработанное исключение и предотвращать сбой приложения.

Есть ли решение для защиты Generic Host, а также 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 : IHostedService
{
    private readonly OpcConfiguration _opcConfiguration;
    private readonly ILogger _logger;
    private readonly OpcClient _opcClient;

    public OpcClientHostedService(OpcConfiguration opcConfiguration, ILogger<OpcClientHostedService> logger)
    {
        _opcConfiguration = opcConfiguration;
        _logger = logger;
        _opcClient = new OpcClient(opcConfiguration.ServerUri);
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Connecting to OPC server with URI '{0}'", _opcConfiguration.ServerUri);
        try
        {
            _opcClient.Connect();
        }
        catch (Exception ex)
        {
            _logger.LogCritical(ex, "Cannot connect to OPC server");
            throw;
        }
        _logger.LogInformation("Connection to OPC server is successful");

        CreateOpcObservable().Subscribe(async args => await ProcessOpcEvent(args));

        return Task.CompletedTask;
    }

    private async Task ProcessOpcEvent(OpcValueChangedEventArgs args)
    {
        await MethodThatCanThrowAnException(args); // If the exception is not handled, the whole application crashes!
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Disconnecting to OPC server");
        _opcClient.Disconnect();
        _logger.LogInformation("Disconnection to OPC server is successful");
        return Task.CompletedTask;
    }

    ...
}

В этом примере легко добавить блок try/catch в ProcessOpcEvent метод, но было бы здорово иметь механизм, чтобы избежать полного сбоя приложения в такой ситуации.

2 ответа

Вы можете добавить обработчик событий на уровне домена приложения, но не сможете контролировать выполнение, продолжая каким-либо определенным образом. Чтобы иметь возможность контролировать выполнение и то, как он обрабатывает исключения, вы ДОЛЖНЫ реализовывать операторы try/catch при обработке сообщений полезной нагрузки OPC.

Вы можете предоставить собственные реализации IHostBuilder и IHost, которые обертывают оригиналы и выявляют ошибки.

См. Этот основной пример , демонстрирующий подход и регистрирующий глобальные ошибки.

Другие вопросы по тегам