/// <summary>
        /// Creates new timers.  This method is thread-safe.
        /// </summary>
        /// <param name="callback">The callback.</param>
        /// <param name="context">The context.</param>
        /// <returns>CountdownTimerTimer.</returns>
        public override CancelationTimer CreateTimer(Callback callback, object context)
        {
            var timer = new CountdownTimerNode(callback, context, Duration, _timers);

            // Add this on the tail.  (Actually, one before the tail - _timers is the sentinel tail.)
            var needProd = false;

            lock (_timers)
            {
                //if (!(_timers.Prev!.Next == _timers))
                //{
                //    NetEventSource.Fail(this, $"Tail corruption.");
                //}

                // If this is the first timer in the list, we need to create a queue handle and prod the timer thread.
                if (_timers.Next == _timers)
                {
                    if (_thisHandle == IntPtr.Zero)
                    {
                        _thisHandle = (IntPtr)GCHandle.Alloc(this);
                    }
                    needProd = true;
                }

                timer.Next        = _timers;
                timer.Prev        = _timers.Prev;
                _timers.Prev.Next = timer;
                _timers.Prev      = timer;
            }

            // If, after we add the new tail, there is a chance that the tail is the next
            // node to be processed, we need to wake up the timer thread.
            if (needProd)
            {
                CountdownTimer.Prod();
            }

            return(timer);
        }