首页 > 解决方案 > TelemetryClient.Flush 没有被 Autofac 调用

问题描述

我的 .NET Framework 4.7.2 控制台应用程序中有以下配置:

var containerBuilder = new ContainerBuilder();

containerBuilder.Register(CreateTelemetryClient).As<TelemetryClient>().OnRelease(HandleTelemetryClientDisposal);
private static void HandleTelemetryClientDisposal(TelemetryClient client)
        {
            client.Flush();
        }

private static TelemetryClient CreateTelemetryClient(IComponentContext context)
        {
            var instrumentationKey = ConfigurationManager.AppSettings["ApplicationInsights:InstrumentationKey"];
            var configuration = TelemetryConfiguration.CreateDefault();
            configuration.InstrumentationKey = instrumentationKey;
            var telemetryClient = new TelemetryClient(configuration);
            telemetryClient.Context.InstrumentationKey = instrumentationKey;
            var telemetryInitializer = context.Resolve<ITelemetryInitializer>();
            configuration.TelemetryInitializers.Add(telemetryInitializer);

            return telemetryClient;
        }

这会为 Application Insights 日志记录正确配置遥测客户端。但是,OnRelease(HandleTelemetryClientDisposal)从未调用过,因此client.Flush()我认为这也是我的日志没有出现在 App Insights 中的原因。

为什么不调用它-我是否配置错误?

编辑以显示更多代码:

class Program
    {
        public static void Main(string[] args)
        {
            var jobHostConfig = new JobHostConfiguration();
            IocConfig.Configure(jobHostConfig );
        }
    }
 public static void Configure(JobHostConfiguration jobHostConfiguratio)
        {
            var containerBuilder = new ContainerBuilder();

            RegisterDependencies(containerBuilder);

            jobHostConfiguration.JobActivator = new AutofacActivator(containerBuilder.Build());
        }
private static void RegisterDependencies(ContainerBuilder containerBuilder) 
{ 

   containerBuilder.Register(CreateTelemetryClient).As<TelemetryClient>().OnRelease(HandleTelemetryClientDisposal);
}

标签: c#.netautofacazure-application-insights

解决方案


很难确切地说出发生了什么,因为我不知道是什么JobHostConfigurationJobActivator或者AutofacActivator是,但是,我知道 Autofac。一些快速的谷歌搜索让我认为这与 Hangfire 有关,所以如果这不能回答你的问题......在问题中提及 Hangfire 和/或标记它可能会很好,hangfire因为它与 Hangfire 有关应用程序生命周期的东西。

OnRelease 在生命周期范围被释放时发生。 我们有一些关于它的文档,但这就是要点 - 这就像添加IDisposable到一个不是一次性的类。有很多文档解释了处置与容器和范围的关系。

从实际的角度来看,这意味着如果Dispose容器或生命周期范围内没有任何调用,您将不会被OnRelease调用。

var builder = new ContainerBuilder();
builder.Register(CreateTelemetryClient)
  .As<TelemetryClient>()
  .OnRelease(HandleTelemetryClientDisposal);
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
  var client = scope.Resolve<TelemetryClient>();

  // When this closing brace is hit, the lifetime scope
  // will be disposed, and the OnRelease will be called.
}

您会注意到我展示了使用生命周期范围的示例。如果您直接从容器中解析,则必须处理容器......然后您就不能再使用容器了。

这就是我对 Hangfire 缺乏了解的地方。我不知道什么时候TelemetryClient解决,我不知道它在使用什么,我不知道它是来自容器还是来自生命周期范围,并且我不知道容器/范围何时被处置。这是您必须弄清楚的事情,但看起来Hangfire.Autofac README 涵盖了一些示例

但是,您描述的症状OnRelease从未被调用所以Flush从未被调用......表明事情没有被正确处理,所以这就是您需要开始寻找的地方。当然,这是假设某些东西首先解决了它 - 如果没有任何东西可以解决它,那么就没有什么可处置的,当然OnRelease也不会被调用。同样,您的代码中没有任何内容显示任何消耗. 客户不会仅仅通过注册就得到解决。有些东西必须消耗它。TelemetryClientOnReleaseTelemetryClient


推荐阅读