예제 #1
0
        public void Cancellation_Test(int jobCount)
        {
            int sequenceLength = jobCount * 10;
            int cancelTreshold = jobCount * 2;
            int resultTreshold = jobCount * 3;

            var cancellationEvent = new AutoResetEvent(false);
            var cancellationToken = new CancellationToken();

            List <int> results = new List <int>();

            Task task = Task.Run(() => {
                IEnumerable <int> values = Sequence(sequenceLength, 5)
                                           .AsParallel(jobCount)
                                           .AsEnumerable(cancellationToken);

                foreach (int value in values)
                {
                    results.Add(value);
                    if (results.Count == cancelTreshold)
                    {
                        cancellationEvent.Set();
                    }
                }
            });

            cancellationEvent.WaitOne();
            cancellationToken.Cancel();

            task.Wait(timeout)
            .Should().BeTrue("Timeout");

            results.Should().HaveCountLessOrEqualTo(resultTreshold);
        }
예제 #2
0
        public void Run(CancellationToken cancellationToken, ProfilingType profilingType)
        {
            Guard.NotNull(cancellationToken, nameof(cancellationToken));

            if (thread != null)
            {
                throw new InvalidOperationException();
            }

            thread = new Thread(() => {
                try {
                    Profiler profiler =
                        profilingType != ProfilingType.None ?
                        new Profiler(name, profilingType) :
                        null;
                    Do(cancellationToken, profiler);
                }
                catch (Exception error) {
                    this.error = error;
                    cancellationToken.Cancel();
                }
                finally {
                    outputChannel.Finish();
                }
            })
            {
                Name         = name,
                IsBackground = true
            };
            thread.Start();
        }
예제 #3
0
        public IEnumerable <T> AsEnumerable(CancellationToken cancellationToken = null, IJobLogger logger = null)
        {
            if (cancellationToken == null)
            {
                cancellationToken = new CancellationToken();
            }

            var errorHandler = new ErrorHandler();

            Job <T>[] jobs = Enumerable.Range(1, jobCount)
                             .Select(i => new Job <T>($"{i}", enumeration, cancellationToken))
                             .ToArray();

            while (true)
            {
                if (HandleErrors(jobs, errorHandler))
                {
                    cancellationToken.Cancel();
                    break;
                }

                if (logger != null)
                {
                    logger.LogResultsCount(jobs.Select(job => job.ResultsCount).Sum());
                }

                List <T> results = new List <T>(jobs.Length);
                foreach (var job in jobs)
                {
                    if (job.TryGetResult(out T result))
                    {
                        results.Add(result);
                    }
                }

                foreach (T result in results)
                {
                    yield return(result);
                }

                if (jobs.All(job => job.IsFinished))
                {
                    HandleErrors(jobs, errorHandler);
                    break;
                }
                else
                {
                    Thread.Sleep(5);
                }
            }

            foreach (var job in jobs)
            {
                job.Dispose();
            }

            errorHandler.ThrowIfFailed();
        }
예제 #4
0
        void Do(CancellationToken cancellationToken, Profiler profiler)
        {
            bool Read(out T data)
            {
                bool finished = true;

                profiler?.BeginWatch(ProfilingType.Read);
                try {
                    finished = inputChannel.Read(out data, profiler);
                }
                finally {
                    profiler?.EndWatch(ProfilingType.Read);
                }
                return(finished);
            }

            U Transform(T data)
            {
                U result = default(U);

                profiler?.BeginWatch(ProfilingType.Transform);
                try {
                    result = transform(data);
                }
                finally {
                    profiler?.EndWatch(ProfilingType.Transform);
                }
                return(result);
            }

            void Write(U data)
            {
                profiler?.BeginWatch(ProfilingType.Write);
                try {
                    outputChannel.Write(data);
                }
                finally {
                    profiler?.EndWatch(ProfilingType.Write);
                }
            }

            while (Read(out T data))
            {
                if (cancellationToken.IsCancelled)
                {
                    break;
                }
                Write(Transform(data));
            }
        }
예제 #5
0
        public Job(string name, IEnumerable <T> enumeration, CancellationToken cancellationToken)
        {
            Guard.NotNull(name, nameof(name));
            Guard.NotNull(enumeration, nameof(enumeration));
            Guard.NotNull(cancellationToken, nameof(cancellationToken));

            this.enumeration       = enumeration;
            this.cancellationToken = cancellationToken;
            thread = new Thread(Run)
            {
                Name         = name,
                IsBackground = true
            };
            thread.Start();
        }