diff --git a/src/Microsoft.AspNet.SignalR.Core/Infrastructure/CancellationTokenExtensions.cs b/src/Microsoft.AspNet.SignalR.Core/Infrastructure/CancellationTokenExtensions.cs index bcb324e06..9af06e492 100644 --- a/src/Microsoft.AspNet.SignalR.Core/Infrastructure/CancellationTokenExtensions.cs +++ b/src/Microsoft.AspNet.SignalR.Core/Infrastructure/CancellationTokenExtensions.cs @@ -10,16 +10,14 @@ namespace Microsoft.AspNet.SignalR.Infrastructure { internal static class CancellationTokenExtensions { - private delegate CancellationTokenRegistration RegisterDelegate(ref CancellationToken token, Action callback, object state); - - private static readonly RegisterDelegate _tokenRegister = ResolveRegisterDelegate(); - public static IDisposable SafeRegister(this CancellationToken cancellationToken, Action callback, object state) { var callbackWrapper = new CancellationCallbackWrapper(callback, state); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. - CancellationTokenRegistration registration = _tokenRegister(ref cancellationToken, InvokeCallback, callbackWrapper); + CancellationTokenRegistration registration = cancellationToken.Register(s => Cancel(s), + callbackWrapper, + useSynchronizationContext: false); var disposeCancellationState = new DiposeCancellationState(callbackWrapper, registration); @@ -27,7 +25,7 @@ namespace Microsoft.AspNet.SignalR.Infrastructure return new DisposableAction(s => Dispose(s), disposeCancellationState); } - private static void InvokeCallback(object state) + private static void Cancel(object state) { ((CancellationCallbackWrapper)state).TryInvoke(); } @@ -37,56 +35,6 @@ namespace Microsoft.AspNet.SignalR.Infrastructure ((DiposeCancellationState)state).TryDispose(); } - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method should never throw since it runs as part of field initialzation")] - private static RegisterDelegate ResolveRegisterDelegate() - { - // The fallback is just a normal register that capatures the execution context. - RegisterDelegate fallback = (ref CancellationToken token, Action callback, object state) => - { - return token.Register(callback, state); - }; - -#if NETFX_CORE || PORTABLE - return fallback; -#else - - MethodInfo methodInfo = null; - - try - { - // By default we don't want to capture the execution context, - // since this is internal we need to create a delegate to this up front - methodInfo = typeof(CancellationToken).GetMethod("InternalRegisterWithoutEC", - BindingFlags.NonPublic | BindingFlags.Instance, - binder: null, - types: new[] { typeof(Action), typeof(object) }, - modifiers: null); - } - catch - { - // Swallow this exception. Being extra paranoid, we don't want anything to break in case this dirty - // reflection hack fails for any reason - } - - // If the method was removed then fallback to the regular method - if (methodInfo == null) - { - return fallback; - } - - try - { - - return (RegisterDelegate)Delegate.CreateDelegate(typeof(RegisterDelegate), null, methodInfo); - } - catch - { - // If this fails for whatever reason just fallback to normal register - return fallback; - } -#endif - } - private class DiposeCancellationState { private readonly CancellationCallbackWrapper _callbackWrapper;