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); }