C# 这个类是否保持创建状态?

C# 这个类是否保持创建状态?,c#,class,timer,dynamic-assemblies,C#,Class,Timer,Dynamic Assemblies,我正在动态加载一个程序集,创建一个实现IRegisterable的类的实例,然后使用以下缩短的代码调用注册方法: public bool RegisterASM(string path) { Assembly asm = LoadAssembly(path); //helper to load assembly if (asm != null) { var registerableTypes = from

我正在动态加载一个程序集,创建一个实现IRegisterable的类的实例,然后使用以下缩短的代码调用注册方法:

    public bool RegisterASM(string path)
    {
        Assembly asm = LoadAssembly(path); //helper to load assembly

        if (asm != null)
        {
            var registerableTypes = from t in asm.GetTypes()
                                    where t.IsClass &&
                                    (t.GetInterface("IRegisterable") != null)
                                    select t;

            foreach (Type t in registerableTypes)
            {
                IRegisterable reg = (IRegisterable)asm.CreateInstance(t.FullName, true);
                reg.Register(this);
            }
            return true;
        }
        else
        {
            Console.WriteLine("Assembly not found");
            return false;
        }
   }
以及IRegisterable类的一个示例:

当类注册时,它调用RegistrationHandler中的一个方法,该方法将依次调用JobScheduler中的一个方法,该方法将创建一个Threading.Timer,TimerCallback是注册中传递的actionMeathod。除此之外,没有其他对IRegisterable类的引用

我的问题是,该类是否会保留在内存中,因为存在对该方法的引用,还是每次调用该方法时都会重新创建该类?还是两者兼而有之

我询问的原因是Class1.Register创建了Class3的一个实例,并将Class3.TestJob3作为actionMeathod传递。当创建Class3时,它设置t=5,这在TestJob3中使用。但是当Register方法退出时,Class3的实例将被销毁,因为它是一个局部变量。但是对Class3.TestJob3的定时调用仍然有t=5,那么Class3是每次都重新创建还是一直存在

但是当Register方法退出时,Class3的实例将被销毁,因为它是一个局部变量

这对于引用类型是不正确的。引用对象是在堆上分配的。局部变量c仅仅指向这个对象。垃圾收集器将在稍后确定未引用该对象时销毁该实例

但是,委托对象操作有一个对Class3对象的引用,因此在可以收集该委托对象本身之前,不会对其进行垃圾收集。因此,Class3实例确实比Register方法的执行时间长,因为在该方法返回后,委托仍将引用它

你可以向自己证明这一点:

Class3 c = new Class3();
actionMeathod = c.TestJob3;
regHandler.RegisterJob(actionMeathod, "Test3", 5000, true);

// Add this line.
Console.WriteLine(object.ReferenceEquals(c, actionMeathod.Target));

输出将为True,表示委托确实具有与c相同的对象的引用。

这取决于您的IRegistrationUtilities.RegisterJob方法的实现。例如,如果它将TestJob的操作放入一个私有变量中,则Class3将保持活动状态,直到垃圾收集器不处理IRegistrationUtilities实例


另外,请注意,即使RegisterJob什么也不做,由于.NET垃圾收集器的不确定性,您的类3也可能不会立即被处置,或者甚至不会与您的应用程序具有相同的使用寿命

这是有道理的,我总是忘记不同类型的变量。如果该类被指定为静态类,显然该类将永远不会被创建,但存储在静态类中的变量将保持正确?@JRLambert correct,并且如果将委托给静态方法,委托的目标属性实际上为null,因为该方法不属于对象实例。如果将委托给值类型为结构的方法,则该结构将被装箱并存储为委托目标。我理解GC的非即时性,我只是担心内存膨胀。@JRLambert,然后关注IRegistrationUtilities如何存储和释放已注册的作业。
Class3 c = new Class3();
actionMeathod = c.TestJob3;
regHandler.RegisterJob(actionMeathod, "Test3", 5000, true);

// Add this line.
Console.WriteLine(object.ReferenceEquals(c, actionMeathod.Target));