【问题标题】:Enumerating disposables tracked by an Autofac lifetime枚举由 Autofac 生命周期跟踪的一次性用品
【发布时间】:2016-09-08 01:32:35
【问题描述】:

Autofac 使用生命周期范围来处理在一个工作单元中创建的所有组件。虽然这是一个强大的功能,但很容易编写无法正确处理生命周期范围的代码,这会导致跟踪的一次性对象的数量随着时间的推移而增加:实际上是内存泄漏。

有没有一种方法可以随时监控 Lifetime Scope 跟踪的 Disposable 对象的数量。我有兴趣编写工具来帮助我找到与未将一次性用品正确分配给工作单元相关的问题。目前我使用内存分析器工具来查找泄漏,但这是一项相当繁重的工作。

我查看了 ILifetimeScope 的公共界面,但没有看到任何有用的东西。

【问题讨论】:

    标签: c# inversion-of-control autofac


    【解决方案1】:

    不幸的是,分析是 Autofac 目前的薄弱环节之一。 There is a repository where some work was started on an analytics package 但肯定有一些差距 - 例如,您可以跟踪对象何时激活,并且您可以查看 生命周期范围 何时被释放,但您不能跟踪单个 对象 何时作为范围的一部分进行处置。只是没有任何活动。

    一个非常简单的激活跟踪模块如下所示:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Autofac;
    using Autofac.Core;
    
    namespace DiagnosticDemo
    {
      public class TrackingModule : Module
      {
        private readonly IDictionary<Type, int> _activations = new Dictionary<Type, int>();
    
        private readonly object _syncRoot = new object();
    
        public void WriteActivations()
        {
          foreach (var pair in this._activations.Where(p => p.Value > 0))
          {
            Console.WriteLine("* {0} = {1}", pair.Key, pair.Value);
          }
        }
    
        protected override void AttachToComponentRegistration(
          IComponentRegistry componentRegistry,
          IComponentRegistration registration)
        {
          if (registration.Ownership == InstanceOwnership.OwnedByLifetimeScope)
          {
            registration.Activated += this.OnRegistrationActivated;
          }
        }
    
        private void OnRegistrationActivated(
          object sender,
          ActivatedEventArgs<object> e)
        {
          if (e.Instance is IDisposable)
          {
            var type = e.Instance.GetType();
            Console.WriteLine("Activating {0}", type);
            lock (this._syncRoot)
            {
              if (this._activations.ContainsKey(type))
              {
                this._activations[type]++;
              }
              else
              {
                this._activations[type] = 1;
              }
            }
          }
        }
      }
    }
    

    你会像这样使用它:

    static void Main(string[] args)
    {
      var trackingModule = new TrackingModule();
    
      var builder = new ContainerBuilder();
      // Register types, then register the module
      builder.RegisterType<Consumer>().As<IConsumer>();
      builder.RegisterType<DisposableDependency>().As<IDependency>();
      builder.RegisterType<NonDisposableDependency>().As<IDependency>();
      builder.RegisterModule(trackingModule);
      var container = builder.Build();
    
      // Do whatever it is you want to do...
      using (var scope = container.BeginLifetimeScope())
      {
        scope.Resolve<IConsumer>();
      }
    
      // Dump data
      Console.WriteLine("Activation totals:");
      trackingModule.WriteActivations();
    }
    

    但是,这不会告诉您哪些项目没有被处置,我认为这是您想知道的。不过,它可能会给你一些想法,或者至少会有所帮助。

    如果您有兴趣帮助改进 Autofac 中的分析,我们很乐意take PRs or specific design ideas for how to improve

    【讨论】:

      【解决方案2】:

      Whitebox 是 Autofac 的一个工作但未完成的 GUI 诊断工具,它几乎可以满足您的需求。它可能需要对最新版本的 Autofac 进行更新 - 欢迎任何有关让项目恢复和运行的帮助。一些docs on the old Google Code page

      【讨论】:

      • 你没有把它移植到我链接的 autofac-analytics repo 中吗?什么是增量?
      • 分析存储库在当前形式下并不能真正使用,我认为 Whitebox 仍然是一种更完整的启动方式。 (除非 Google Analytics(分析)向前发展而我错过了 :-))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 2010-09-17
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多