簡體   English   中英

.NET 通用主機:防止應用程序因未處理的異常而崩潰

[英].NET Generic Host : Prevent application crash on unhandled exception

我有一個帶有IHostedService的 .NET 通用主機,它從 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 : 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;
    }

    ...
}

在這個例子中,很容易在ProcessOpcEvent方法中添加一個 try/catch 塊,但是如果有一種機制可以避免在這種情況下應用程序完全崩潰,那就太好了。

您可以添加應用程序域級別的事件處理程序,但您將無法以任何特定方式控制繼續執行。 為了能夠控制執行及其處理異常的方式,您必須在處理 OPC 有效負載消息時實施 try/catch 語句。

您可以提供自定義IHostBuilderIHost實現來包裝原始文件並捕獲錯誤。

請參閱此gist 示例,該示例演示了該方法並記錄了全局錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM