有時用戶想要安排一大組定時器,並且不想管理對這些定時器的引用。
如果用戶沒有引用定時器,定時器可能會在GC執行之前被GC收集。
我創建的類定時器,以作爲新創建的計時器的佔位符:定時器代理周圍的內存泄漏
static class Timers
{
private static readonly ILog _logger = LogManager.GetLogger(typeof(Timers));
private static readonly ConcurrentDictionary<Object, Timer> _timers = new ConcurrentDictionary<Object, Timer>();
/// <summary>
/// Use this class in case you want someone to hold a reference to the timer.
/// Timer without someone referencing it will be collected by the GC even before execution.
/// </summary>
/// <param name="dueTime"></param>
/// <param name="action"></param>
internal static void ScheduleOnce(TimeSpan dueTime, Action action)
{
if (dueTime <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException("dueTime", dueTime, "DueTime can only be greater than zero.");
}
Object obj = new Object();
Timer timer = new Timer(state =>
{
try
{
action();
}
catch (Exception ex)
{
_logger.ErrorFormat("Exception while executing timer. ex: {0}", ex);
}
finally
{
Timer removedTimer;
if (!_timers.TryRemove(obj, out removedTimer))
{
_logger.Error("Failed to remove timer from timers");
}
else
{
removedTimer.Dispose();
}
}
});
if (!_timers.TryAdd(obj, timer))
{
_logger.Error("Failed to add timer to timers");
}
timer.Change(dueTime, TimeSpan.FromMilliseconds(-1));
}
}
如果我不處置刪除計時器,它導致內存泄漏。
似乎某人在定時器從_timers
集合中刪除之後持有對定時器委託的引用。
問題是,如果我不處理定時器,爲什麼會發生內存泄漏?
也許我不明白你在問什麼,因爲它聽起來像你想知道爲什麼當你虐待它的東西行爲不端... –
據我所知,該文件說組件應該處置。我仍然很好奇,什麼阻止GC收集計時器和給定的委託,而無需調用dispose方法。 –