예제 #1
0
        public static void Run <TState>(ReplicatableUserAction <TState> action, ParallelOptions options, bool stopOnFirstFailure)
        {
            // Browser hosts do not support synchronous Wait so we want to run the
            //  replicated task directly instead of going through Task infrastructure
            if (OperatingSystem.IsBrowser())
            {
                // Since we are running on a single thread, we don't want the action to time out
                var timeout = int.MaxValue - 1;
                var state   = default(TState) !;

                action(ref state, timeout, out bool yieldedBeforeCompletion);
                if (yieldedBeforeCompletion)
                {
                    throw new Exception("Replicated tasks cannot yield in this single-threaded browser environment");
                }
            }
            else
            {
                int maxConcurrencyLevel = (options.EffectiveMaxConcurrencyLevel > 0) ? options.EffectiveMaxConcurrencyLevel : int.MaxValue;

                TaskReplicator replicator = new TaskReplicator(options, stopOnFirstFailure);
                new Replica <TState>(replicator, maxConcurrencyLevel, CooperativeMultitaskingTaskTimeout_RootTask, action).Start();

                Replica?nextReplica;
                while (replicator._pendingReplicas.TryDequeue(out nextReplica))
                {
                    nextReplica.Wait();
                }

                if (replicator._exceptions != null)
                {
                    throw new AggregateException(replicator._exceptions);
                }
            }
        }
예제 #2
0
            protected volatile Task _pendingTask; // the most recently queued Task for this replica, or null if we're done.

            protected Replica(TaskReplicator replicator, int maxConcurrency, int timeout)
            {
                _replicator           = replicator;
                _timeout              = timeout;
                _remainingConcurrency = maxConcurrency - 1;
                _pendingTask          = new Task(s => ((Replica)s).Execute(), this);
                _replicator._pendingReplicas.Enqueue(this);
            }
예제 #3
0
 protected Replica(TaskReplicator replicator, int maxConcurrency, int timeout)
 {
     Replicator           = replicator;
     Timeout              = timeout;
     RemainingConcurrency = maxConcurrency - 1;
     PendingTask          = new Task(Execute);
     Replicator._pendingReplicas.Enqueue(this);
 }
예제 #4
0
        public static void Run <TState>(ReplicableUserAction <TState> action, ParallelOptions options, bool stopOnFirstFailure)
        {
            var maxConcurrencyLevel = options.EffectiveMaxConcurrencyLevel > 0 ? options.EffectiveMaxConcurrencyLevel : int.MaxValue;

            var replicator = new TaskReplicator(options, stopOnFirstFailure);

            new Replica <TState>(replicator, maxConcurrencyLevel, _cooperativeMultitaskingTaskTimeoutRootTask, action).Start();

            while (replicator._pendingReplicas.TryDequeue(out var nextReplica))
            {
                nextReplica.Wait();
            }

            if (replicator._exceptions != null)
            {
                throw new AggregateException(replicator._exceptions);
            }
        }