// ReSharper restore RedundantOverridenMember /// <summary> /// Suspends the change callbacks whenever a property has been called. This is very useful when /// there are expensive property change callbacks registered with a property that need to be /// temporarily disabled. /// </summary> /// <returns></returns> public IDisposable SuspendChangeCallbacks() { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_changeCallbacksSuspensionContext == null) { _changeCallbacksSuspensionContext = new SuspensionContext(); } _changeCallbacksSuspensionContext.Increment(); } }, x => { lock (_lock) { var suspensionContext = _changeCallbacksSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeCallbacksSuspensionContext = null; } } } // Note: don't invoke the "missed" callbacks }); return(token); }
public static dynamic GetTSObject(DisposableToken dynObject) { if (dynObject is null) { return(null); } return(dynObject.teklaObject); }
public static IDisposable Navigate(NavigationRequest navigationRequest, INavigationHandler navigationHandler, Action <ResponseStatus> statusCallback) { Guard.ArgumentNotNull(navigationRequest, "navigationRequest"); Guard.ArgumentNotNull(navigationHandler, "navigationHandler"); // if the request already had a token then dispose it if (navigationRequest.Token != null) { navigationRequest.Token.Dispose(); } // create a new token var _disposableToken = new DisposableToken(); navigationRequest.Token = _disposableToken; // and process the response navigationHandler.ProcessRequest(navigationRequest, async(b) => { // if the handler will not process it - note we don't return the if (!b) { statusCallback.Notify(ResponseStatus.Cancelled); _disposableToken.Dispose(); return; } // if the token was already disposed then we tell the handler it was cancelled if (_disposableToken.IsDisposed) { statusCallback.Notify(ResponseStatus.Cancelled); await navigationHandler.ProcessResponseAsync(new NavigationResponse(navigationRequest, ResponseStatus.Cancelled, null, null)); return; } // we delegate to the routing engine Resolve(navigationRequest, async(r) => { // if not cancelled if (!_disposableToken.IsDisposed) { await navigationHandler.ProcessResponseAsync(r); statusCallback.Notify(r.Status); } else { await navigationHandler.ProcessResponseAsync(new NavigationResponse(navigationRequest, ResponseStatus.Cancelled, null, null)); statusCallback.Notify(ResponseStatus.Cancelled); } }); }); return(_disposableToken); }
/// <summary> /// Suspends the validation until the disposable token has been disposed. /// </summary> /// <returns></returns> public IDisposable SuspendValidations(bool validateOnResume = true) { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_validationSuspensionContext == null) { _validationSuspensionContext = new SuspensionContext(); } _validationSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_lock) { suspensionContext = _validationSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _validationSuspensionContext = null; } } } if (suspensionContext != null && suspensionContext.Counter == 0) { if (!validateOnResume) { // Only catch up what we missed var properties = suspensionContext.Properties; foreach (var property in properties) { ValidatePropertyUsingAnnotations(property); } } else { // We need to force validation on attributes again with this flag Validate(true, true); } } }); return(token); }
private void ReturnLock(DisposableToken disposableLock) { var obj = disposableLock.LockObject; lock (keyLocksLock) { if (obj.Return()) { keyLocks.Remove(obj.Key); } Monitor.Exit(obj); } }
/// <summary> /// Suspends the change notifications until the disposed object has been released. /// </summary> /// <param name="raiseOnResume">if set to <c>true</c>, the notifications are invoked on resume.</param> /// <returns>A disposable object.</returns> public IDisposable SuspendChangeNotifications(bool raiseOnResume = true) { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_changeNotificationsSuspensionContext == null) { _changeNotificationsSuspensionContext = new SuspensionContext(); } _changeNotificationsSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_lock) { suspensionContext = _changeNotificationsSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeNotificationsSuspensionContext = null; } } } if (raiseOnResume) { if (suspensionContext != null && suspensionContext.Counter == 0) { var properties = suspensionContext.Properties; foreach (var property in properties) { RaisePropertyChanged(property); } } } }); return(token); }
/// <summary> /// Suspends the validation until the disposable token has been disposed. /// </summary> /// <returns></returns> public IDisposable SuspendValidations(bool validateOnResume = true) { var token = new DisposableToken<ModelBase>(this, x => { lock (_validationLock) { if (_validationSuspensionContext == null) { _validationSuspensionContext = new SuspensionContext(); } _validationSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_validationLock) { suspensionContext = _validationSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _validationSuspensionContext = null; } } } if (validateOnResume) { if (suspensionContext != null && suspensionContext.Counter == 0) { //var properties = suspensionContext.Properties; // TODO: In v5, replace with context and smart validation Validate(true, true); //foreach (var property in properties) //{ // Validate(property); //} } } }); return token; }
/// <summary> /// Suspends the change notifications until the disposed object has been released. /// </summary> /// <param name="raiseOnResume">if set to <c>true</c>, the notifications are invoked on resume.</param> /// <returns>A disposable object.</returns> public IDisposable SuspendChangeNotifications(bool raiseOnResume = true) { var token = new DisposableToken<ModelBase>(this, x => { lock (_propertyValuesLock) { if (_changeNotificationsSuspensionContext == null) { _changeNotificationsSuspensionContext = new SuspensionContext(); } _changeNotificationsSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_propertyValuesLock) { suspensionContext = _changeNotificationsSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeNotificationsSuspensionContext = null; } } } if (raiseOnResume) { if (suspensionContext != null && suspensionContext.Counter == 0) { var properties = suspensionContext.Properties; foreach (var property in properties) { RaisePropertyChanged(property); } } } }); return token; }
/// <summary> /// Suspends the change callbacks whenever a property has been called. This is very useful when /// there are expensive property change callbacks registered with a property that need to be /// temporarily disabled. /// </summary> /// <returns></returns> public IDisposable SuspendChangeCallbacks() { var token = new DisposableToken<ModelBase>(this, x => { lock (_propertyValuesLock) { if (_changeCallbacksSuspensionContext == null) { _changeCallbacksSuspensionContext = new SuspensionContext(); } _changeCallbacksSuspensionContext.Increment(); } }, x => { lock (_propertyValuesLock) { var suspensionContext = _changeCallbacksSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeCallbacksSuspensionContext = null; } } } // Note: don't invoke the "missed" callbacks }); return token; }
public void ThrowsOnNullDisposeAction() { var token = new DisposableToken(null); }