这门课是否留下来了?

时间:2014-08-20 16:59:17

标签: 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 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类的一个例子:

public class Class1 : IRegisterable
{

    public bool Register(IRegistrationUtilities regHandler)
    {
        Action<Dictionary<string, object>> actionMeathod = TestJob;
        regHandler.RegisterJob(actionMeathod, "Testing", 30000, true);

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

    public void TestJob(Dictionary<string, object> vars)
    {
        Console.WriteLine("SleepStart");
        Thread.Sleep(40000);
        Console.WriteLine("SleepEnd");
    }
}

public class Class3
{
    int t = 5;

    public void TestJob3(Dictionary<string, object> vars)
    {
        Console.WriteLine("test 3...{0}", t);
    }
}

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

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

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

2 个答案:

答案 0 :(得分:0)

  

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

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

但是,委托对象(Action<Dictionary<string, object>>)具有对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));

输出将为&#34; True&#34;,表示委托确实具有对c所做的同一对象的引用。

答案 1 :(得分:0)

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

另请注意,即使RegisterJob没有做任何事情,由于.NET垃圾的不确定性,您的Class3可能不会立即处理(甚至与您的申请的生命周期相同)集电极。