private Register ( System.Action callback, bool useSynchronizationContext ) : System.Threading.CancellationTokenRegistration | ||
callback | System.Action | |
useSynchronizationContext | bool | |
Результат | 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)); }
public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext) { if (callback == null) { throw new ArgumentNullException(nameof(callback)); } return(_source?.Register(callback, useSynchronizationContext) ?? new CancellationTokenRegistration()); }
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; }