c# - 在瞬态生命周期服务中记录火灾并忘记任务的异常
问题描述
我有一个火而忘记的任务,我需要报告一些遥测,任务是否成功都没有关系(这就是为什么它是火而忘记),但我需要确保它不会阻塞 api 调用.
当遥测任务中出现异常时,我会记录异常。
我的代码是这样的:
public class MyService : IMyService
{
private readonly IReporter reporter;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public MyService (IReporter reporter){
}
//..
public Task<Result> processorRequest()
{
// ...
_ = Task.Run(() =>
{
reportTelemetry();
});
//...
}
private void reportTelemetry()
{
try
{
reporter.Report();
}
catch (Exception ex)
{
logger.Warn($"An exception was raised while reporting: {ex.Message}");
}
}
}
记录器在顶部创建,如下所示:
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
MyService
并且它们Reporter
被创建并注入到具有瞬态生命周期的容器中。
我的问题是:
新线程中对记录器的引用会阻止MyService
/Reporter
被收集吗?logger.Warn
或者 GC 会在调用之前就决定释放服务吗?
由于某种原因(除了应用程序关闭),我是否有风险不报告异常?
任何帮助深表感谢。
解决方案
新线程中对记录器的引用会阻止收集 MyService/Reporter 吗?
不,但是对 的引用this
将确保服务保持活动状态,直到委托开始运行。lambda 本质上将被重写为
public class MyHiddenDelegate{
private MyService service;
public MyHiddenDelegate(MyService service) => this.service = service;
public void Execute() => service.reportTelemetry();
}
并且这个对象将被执行线程的堆栈或任务队列引用。但是logger
由于它是一个静态字段,因此对于任何对象的生命周期并没有真正发挥任何作用。
或者 GC 会在调用 logger.Warn 之前决定释放服务吗?
GC 必须保持对象处于活动状态,直到最后一次使用任何引用。因此,该服务可能有资格在调用 之前进行收集logger.Warn
,因为它不需要this
引用来访问记录器。但这通常很好,因为 GC 将确保在最后一次使用之前没有收集任何内容。
如果您拥有本机资源,则可能是一个例外。然后,您可能需要使用GC.KeepAlive来确保在完成本机资源之前不会运行终结器。
由于某种原因(除了应用程序关闭),我是否有风险不报告异常?
据我所知,不是因为任何收藏问题。但可能还有其他考虑因素,例如无法捕获的异常。
推荐阅读
- windows - Windows 10 上的 Apache 2.4.46 虚拟主机
- c# - Blazor EditForm 以编程方式提交
- spring-boot - 在哪里可以找到 SpringBoot 包的 SHA256/SHA512 哈希?
- javascript - 如何将嵌入查询与 wordpress rest api 一起使用?
- powerbi - 如何在 PowerBI 中使用 DAX 创建动态子表
- php - 我需要为每个重复输入创建一个新的 id 吗?
- octave - 为 Octave 安装 Rainflow 算法
- javascript - 如何使用 React Native 将图像上传到 Web 服务器
- python - 您可以从 numpy 数组或 pandas 数据帧中提取超过阈值的数据索引吗
- r - 使用 r 对每一行进行条件计数