我动态加载程序集,创建实现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.Timer
,TimerCallback
为actionMeathod
注册中传递的IRegisterable
。除此之外,没有其他对Class1.Register
类的引用。
我的问题是,该类是否保留在内存中,因为有对该方法的引用或者每次调用该方法时都会重新创建该类?或两者兼而有之?
我问的原因是Class3
创建了Class3.TestJob3
的实例,并将actionMeathod
作为Class3
传递。创建t=5
后,会设置TestJob3
,Register
中使用Class3
。但是当Class3.TestJob3
方法退出时,t=5
的实例将被销毁,因为它是一个局部变量。但是对Class3
的定时通话仍然有{{1}},那么每次都会重新创建{{1}}还是一直存在?
答案 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
可能不会立即处理(甚至与您的申请的生命周期相同)集电极。