Callbacks can occur after the Timer.Dispose method overload has been called, because the timer queues callbacks for execution by thread pool threads. You can use the Timer.Dispose(WaitHandle) method overload to wait until all callbacks have completed.