Skip to content

Instantly share code, notes, and snippets.

@davidfowl
Last active September 4, 2018 00:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidfowl/1b8d5c13f8c93b2333bef699ea9d1a45 to your computer and use it in GitHub Desktop.
Save davidfowl/1b8d5c13f8c93b2333bef699ea9d1a45 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Threading;
namespace TimersAreWeird
{
public class Program
{
public static void Main(string[] args)
{
var timers = new List<Timer>();
while (true)
{
Console.Write("Waiting for input: ");
var c = Console.ReadKey();
Console.WriteLine();
if (c.Key == ConsoleKey.G)
{
Console.WriteLine("Collecting garbage");
GC.Collect();
}
else if (c.Key == ConsoleKey.H)
{
Console.WriteLine("Collecting garbage for gen 2 and waiting for finalizers");
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
}
else if (c.Key == ConsoleKey.D)
{
lock (timers)
{
Console.WriteLine(timers.Count);
}
}
else if (c.Key == ConsoleKey.F5)
{
Console.WriteLine("Refreshing");
Timer timer = null;
timer = new Timer(state =>
{
timer.Dispose();
lock (timers)
{
timers.Remove(timer);
}
},
null, 1000, Timeout.Infinite);
lock (timers)
{
timers.Add(timer);
}
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Threading;
namespace TimersAreWeird
{
public class Program
{
public static void Main(string[] args)
{
var refs = new ExpiredReferencesManager();
while (true)
{
Console.Write("Waiting for input: ");
var c = Console.ReadKey();
Console.WriteLine();
if (c.Key == ConsoleKey.G)
{
Console.WriteLine("Collecting garbage");
GC.Collect();
}
else if (c.Key == ConsoleKey.H)
{
Console.WriteLine("Collecting garbage for gen 2 and waiting for finalizers");
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
}
else if (c.Key == ConsoleKey.D)
{
refs.Dump();
}
else if (c.Key == ConsoleKey.F5)
{
Console.WriteLine("Refreshing");
ThreadPool.QueueUserWorkItem(state =>
{
var manager = (ExpiredReferencesManager)state;
manager.Make();
},
refs);
}
}
}
}
public class Expired
{
private Timer _timer;
private Action<Expired> _expiredCallback;
private static readonly TimerCallback _timerCallback = OnExpired;
public object Item { get; private set; }
public Expired(object thing)
{
Item = thing;
}
public void StartTimer(Action<Expired> callback)
{
_expiredCallback = callback;
_timer = new Timer(_timerCallback, this, 1000, Timeout.Infinite);
}
private static void OnExpired(object state)
{
var expired = (Expired)state;
expired._timer.Dispose();
expired._timer = null;
var callback = expired._expiredCallback;
expired._expiredCallback = null;
callback(expired);
expired.Item = null;
}
}
public class ExpiredReferencesManager
{
private readonly List<WeakReference> _expiredItems = new List<WeakReference>();
public object Make()
{
var obj = new Expired(new object());
obj.StartTimer(OnExpired);
return obj.Item;
}
private void OnExpired(Expired obj)
{
lock (_expiredItems)
{
_expiredItems.Add(new WeakReference(obj.Item));
}
}
internal void Dump()
{
lock (_expiredItems)
{
foreach (var item in _expiredItems)
{
Console.WriteLine(item.IsAlive);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment