public static void SetState(this CancellationTokenSource source, object state)
 {
     if (source is CancellationTokenSourceWithState sourceWithState)
     {
         sourceWithState.State = state;
     }
     else
     {
         CancellationTokenSourceStateHolder.Get(source).State = state;
     }
 }
 public static object GetState(this CancellationTokenSource source)
 {
     if (source is CancellationTokenSourceWithState sourceWithState)
     {
         return(sourceWithState.State);
     }
     else
     {
         return(CancellationTokenSourceStateHolder.Get(source).State);
     }
 }
        public static CancellationTokenSourceStateHolder Get(CancellationTokenSource source)
        {
            CancellationTokenSourceStateHolder holder;
            var timer = source.GetTimer();

            if (timer != null)
            {
                timer.GetCallbackAndState(out var callback, out var state);
                holder = state as CancellationTokenSourceStateHolder;
                if (holder != null)
                {
                    return(holder);
                }
            }

            holder = new CancellationTokenSourceStateHolder
            {
                _source = source
            };

            if (timer != null)
            {
                timer.SetCallbackAndState(_timerCallback, holder);
            }
            else
            {
#warning SuppressFlow is supported in .NET Standard 2.0, also why is it needed here?
#if NETFX
                using (ExecutionContext.SuppressFlow())
#endif
                {
                    timer = new Timer(_timerCallback, holder, -1, -1);
                }
                source.SetTimer(timer);
            }

            return(holder);
        }