我刚从C#开始,这是我的第一个问题,如果这是愚蠢或错误的问题,请道歉......
我有一个计时器列表:
private List<MyTimerClass> MyTimerClassList = new List<MyTimerClass>();
其中MyTimerClass
只包含一个值来跟踪此计时器的ID以及初始化它的方法:
timer = new System.Timers.Timer();
我正在使用ElapsedEventHandler
以标准方式设置这些计时器:
foreach (var p in AnotherList)
{
var t = new MyTimerClass();
t.init_timer();
t.id = MyOtherClass.ID;
t.timer.Interval = p.Interval;
t.timer.Elapsed += new ElapsedEventHandler((source, e) => RunMyTimerEvent(source, e, p));
t.timer.Enabled = true;
MyTimerClassList.Add(t);
};
这些计时器旨在无限期地运行,并且事件处理程序运行一些异步Web内容。有时,程序可能会获得一些信息,要求它重新安排,添加或删除任何或所有这些计时器,因此我有另一个计时器事件定期检查更新计划并在需要时重新配置上述任何计时器:
// first check to see see if a timer should be removed
foreach (var t in MyTimerClassList)
{
if (!(UpdatedListofTimers.Exists(p => p.ID == t.id)))
{
t.timer.Stop();
t.timer.Dispose();
}
}
// then check to see if any of the timer intervals has been changed
foreach (var t in UpdatedAnotherList)
{
var item = MyTimerClassList.Find(p => p.id == MyTimerClass.ID);
if (item != null)
{
if (item.timer.Interval != (t.interval * 1000))
{
item.timer.Stop();
item.timer.Interval = (t.Interval * 1000);
item.timer.Start();
}
}
// leaves us with adding a new timer
else {
var n = new MyTimerClass();
n.init_timer();
n.id = t.ID;
n.timer.Interval = t.interval * 1000;
n.timer.Elapsed += new ElapsedEventHandler((sender, ev) => RunMyTimerEvent(sender, ev, t));
n.timer.Enabled = true;
MyTimerClassList.Add(n);
}
};
代码有效;它工作正常,计时器更新,重新安排和重新配置,他们应该发射事件并做他们的东西。计时器处理程序事件基本上是对从任务开始的方法的调用:
public void RunMyTimerEvent(object source, ElapsedEventArgs e, AnotherList x)
{
Task<int> t = Task.Run(() => AsyncProcessClass.SomeAsyncStuff(x));
t.Wait();
t.Dispose();
}
问题在于存在巨大的内存泄漏,内存使用速度非常快,即使拨打GC.Collect
也没有收集垃圾。在我呼叫的async
进程中,没有任何内存泄漏或处理程序没有被处理掉(而且我知道你不会这样做必须处理的东西,垃圾收集器足够聪明,知道什么不再参考)。
如果我在获得更新时不再重新配置计时器,而是将它们全部删除并从头开始重新创建,内存泄漏就会消失。我在这里做错了吗?而不是像现在这样改变计时器间隔,你是否必须删除它并创建一个新的?另一个计时器事件可以重新配置不同的计时器吗?它是事件处理程序中的方法的弱引用问题,它永远不会被标记为垃圾收集?我不太了解弱引用,至少不足以尝试它。也许我做了一些明显错误的事情?