示例#1
0
        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();
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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();
                }
            }
        }
示例#5
0
        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);
        }
示例#6
0
 public void Cancel(TimeSpan cancelTimeout, ForcedCancellationMode forcedCancellationMode)
 {
     this.remoteProxy.Cancel(cancelTimeout, forcedCancellationMode);
 }