我有一个带有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块,但是拥有一种避免这种情况下应用程序完全崩溃的机制将非常有用。
答案 0 :(得分:2)
您可以添加应用程序域级别的事件处理程序,但无法以任何特定方式控制执行的继续。为了能够控制执行及其如何处理异常,必须在处理OPC有效负载消息时实施try / catch语句。
答案 1 :(得分:0)
您可以提供自定义 IHostBuilder 和 IHost 实现来包装原始文件并捕获错误。
请参阅演示该方法并记录全局错误的 gist sample。