【问题标题】:Logging exception for a fire and forget task in a transient lifetime service在瞬态生命周期服务中记录火灾并忘记任务的异常
【发布时间】:2023-04-04 03:10:01
【问题描述】:

我有一个触发后忘记的任务,我需要报告一些遥测数据,无论任务是否成功(这就是触发后忘记的原因),但我需要确保它不会阻塞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();

MyServiceReporter 被创建并注入到具有 transient 生命周期的容器中。

我的问题是:

新线程中对 logger 的引用会阻止 MyService/Reporter 被收集吗?或者 GC 会在调用 logger.Warn 之前就决定释放服务吗?

我是否会因为某种原因(除了应用关闭)而不报告异常情况?

非常感谢任何帮助。

【问题讨论】:

    标签: c# multithreading logging task unity-container


    【解决方案1】:

    新线程中对 logger 的引用会阻止 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 来确保在您完成本机资源之前不会运行终结器。

    我是否会因为某种原因(除了应用关闭)而不报告异常情况?

    据我所知,不是因为任何收集问题。但可能还有其他考虑因素,例如无法捕获的异常。

    【讨论】:

      猜你喜欢
      • 2016-12-03
      • 2020-10-10
      • 2017-03-08
      • 2016-06-21
      • 1970-01-01
      • 2019-03-17
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多