public async Task InvokeAsync( Expression <Action <CancellationToken> > invocation, CancellationToken ct = new CancellationToken(), TimeSpan?cancellationTimeout = null, ForcedCancellationMode forcedCancellationMode = ForcedCancellationMode.CleanupAfterCancellation, SecurityZone securityZone = SecurityZone.MyComputer, WorkerProcessRef workerProcessRef = null ) { if (this.disposed) { throw new ObjectDisposedException("This instance has been disposed."); } try { this.standbyTask.Cancel(); var nextWorker = await this.ActivateWorker(ct); await nextWorker .InvokeRemotely(invocation, ct, cancellationTimeout.GetValueOrDefault(this.defaultCancellationTimeout), forcedCancellationMode, securityZone, workerProcessRef); } finally { this.standbyTask.Reset(); } }
private async Task EnsureCanceled( TimeSpan cancelTimeout, ForcedCancellationMode forcedCancellationMode, CancellationToken ct ) { if (forcedCancellationMode == ForcedCancellationMode.KillImmediately) { this.CommitSuicide(); } var asyncCancellation = forcedCancellationMode == ForcedCancellationMode.CleanupAfterCancellation; var halfCancelTimeout = TimeSpan.FromMilliseconds(cancelTimeout.TotalMilliseconds / 2); try { await Task.Delay(asyncCancellation?cancelTimeout : halfCancelTimeout, ct).ConfigureAwait(false); } catch (TaskCanceledException) { return; } if (!asyncCancellation) { // ReSharper disable once UnusedVariable var cleanupTask = this.CleanupWatchdog(halfCancelTimeout, ct); } this.Cleanup(false, asyncCancellation); }
public async Task InvokeRemotely( Expression <Action <CancellationToken> > invocation, CancellationToken ct, TimeSpan cancellationTimeout, ForcedCancellationMode forcedCancellationMode, SecurityZone securityZone, WorkerProcessRef workerProcessRef ) { var request = InvocationRequest.FromExpression(invocation); await this.InvokeRemotely( request, ct, cancellationTimeout, forcedCancellationMode, securityZone, workerProcessRef) .ConfigureAwait(false); }
public void Cancel( TimeSpan cancelTimeout, ForcedCancellationMode forcedCancellationMode ) { if (forcedCancellationMode == ForcedCancellationMode.KillImmediately) { this.CommitSuicide(); } lock (this.stateLock) { if (this.activeRunner != null && this.cleanupTaskCts == null) { this.cleanupTaskCts = new CancellationTokenSource(); // ReSharper disable once UnusedVariable var ensureCanceledTask = this.EnsureCanceled( cancelTimeout, forcedCancellationMode, this.cleanupTaskCts.Token); this.activeRunner.Cancel(); } } }
private Task <object> InvokeRemotely( InvocationRequest request, CancellationToken ct, TimeSpan cancellationTimeout, ForcedCancellationMode forcedCancellationMode, SecurityZone securityZone, WorkerProcessRef workerProcessRef ) { const State nextState = State.Busy; lock (this.stateLock) { if (this.CurrentState != State.Idle) { throw new InvalidOperationException( "Worker process is not ready. Current state is: " + this.CurrentState); } if (!this.process.IsAlive) { this.OnProcessDead(this, EventArgs.Empty); throw new InvalidOperationException("Worker process not alive / crashed."); } this.state = nextState; this.activeTcs = new TaskCompletionSource <object>(); if (workerProcessRef != null) { workerProcessRef.WorkerProcess = this.process.Process; } // this is the latest time to check whether the task has already been cancelled, before actually // starting the task! if (ct.IsCancellationRequested) { this.activeTcs.TrySetCanceled(); this.activeTcs = null; return(this.activeTcs.Task); } } // outside lock! this.OnCurrentStateChanged(nextState); ct.Register(() => { try { this.serverProxy.Cancel(cancellationTimeout, forcedCancellationMode); } catch (RemotingException) { if (!this.process.IsAlive) { // worker killed itself or crashed: ignore! return; } throw; } }); this.serverProxy.InvokeAsync(request.ToPortableInvocationRequest(), securityZone); // Calling Cancel(..) on the server is only handled if there's a invocation request being handled! // there's the chance that task was canceled before it was actually started. It might have happened // before registering the cancel callback, as well. // At this point we now for sure, that the task has been started! if (ct.IsCancellationRequested) { this.serverProxy.Cancel(cancellationTimeout, forcedCancellationMode); } return(this.activeTcs.Task); }
public void Cancel(TimeSpan cancelTimeout, ForcedCancellationMode forcedCancellationMode) { this.remoteProxy.Cancel(cancelTimeout, forcedCancellationMode); }