Register() private method

private Register ( System.Action callback, bool useSynchronizationContext ) : System.Threading.CancellationTokenRegistration
callback System.Action
useSynchronizationContext bool
return System.Threading.CancellationTokenRegistration
 /// <summary>
 /// Registers a callback to be invoked when this CancellationToken is cancelled.
 /// </summary>
 /// <param name="callback">The action to be invoked.</param>
 /// <returns>A registration object that can be used to deregister the callback.</returns>
 public CancellationTokenRegistration Register(Action callback)
 {
     if (source != null)
     {
         return(source.Register(callback));
     }
     return(default(CancellationTokenRegistration));
 }
Esempio n. 2
0
        public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext)
        {
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            return(_source?.Register(callback, useSynchronizationContext) ?? new CancellationTokenRegistration());
        }
Esempio n. 3
0
        public static Task<CancellationToken> FromTimeoutAsync(int millisecondsTimeout)
        {
            // Note that CancellationTokenSource constructor requires input to be >= -1,
            // restricting millisecondsTimeout to be >= -1 would enforce that
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("Invalid millisecondsTimeout value " + millisecondsTimeout);
            }

            uint currentTime = (uint)Environment.TickCount;
            long targetTime = millisecondsTimeout + currentTime;
            // round the targetTime up to the next closest 15ms
            targetTime = ((targetTime + (COALESCING_SPAN_MS - 1)) / COALESCING_SPAN_MS) * COALESCING_SPAN_MS;

            Task<CancellationToken> tokenTask;

            if (!s_tokenCache.TryGetValue(targetTime, out tokenTask))
            {
                var tcs = new TaskCompletionSource<CancellationToken>();

                // only a single thread may succeed adding its task into the cache
                if (s_tokenCache.TryAdd(targetTime, tcs.Task))
                {
                    // Since this thread was successful reserving a spot in the cache, it would be the only thread
                    // that construct the CancellationTokenSource
                    var token = new CancellationTokenSource((int)(targetTime - currentTime)).Token;

                    // Clean up cache when Token is canceled
                    token.Register(t => {
                        Task<CancellationToken> ignored;
                        s_tokenCache.TryRemove((long)t, out ignored);
                    }, targetTime);

                    // set the result so other thread may observe the token, and return
                    tcs.TrySetResult(token);
                    tokenTask = tcs.Task;
                }
                else
                {
                    // for threads that failed when calling TryAdd, there should be one already in the cache
                    if (!s_tokenCache.TryGetValue(targetTime, out tokenTask))
                    {
                        // In unlikely scenario the token was already cancelled and timed out, we would not find it in cache.
                        // In this case we would simply create a non-coalsed token
                        tokenTask = Task.FromResult(new CancellationTokenSource(millisecondsTimeout).Token);
                    }
                }
            }
            return tokenTask;
        }