public void EnsureThreadedTaskSchedulerProcessesBeforeDispose()
        {
            int runCount = 0;

            const int target_count = 128;

            using (var taskScheduler = new ThreadedTaskScheduler(4, "test"))
            {
                for (int i = 0; i < target_count; i++)
                {
                    Task.Factory.StartNew(() =>
                    {
                        Interlocked.Increment(ref runCount);
                        Thread.Sleep(100);
                    }, default, TaskCreationOptions.HideScheduler, taskScheduler);
Ejemplo n.º 2
0
 public ThreadedTaskSchedulerDebugView(ThreadedTaskScheduler scheduler)
 {
     Scheduler = scheduler ?? ThrowHelper.ThrowArgumentNullException <ThreadedTaskScheduler>(nameof(scheduler));
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Start running the queue.
        /// </summary>
        /// <param name="cancellation">An optional cancellation token.</param>
        public void Run(CancellationToken cancellation = default)
        {
            using (new Timer(_ => outputStats(), null, TimeSpan.Zero, TimeSpan.FromSeconds(5)))
                using (var cts = new GracefulShutdownSource(cancellation))
                {
                    Console.WriteLine($"Starting queue processing (Backlog of {GetQueueSize()})..");

                    using (var threadPool = new ThreadedTaskScheduler(Environment.ProcessorCount, "workers"))
                    {
                        var database = redis.GetDatabase();

                        while (!cts.Token.IsCancellationRequested)
                        {
                            if (consecutiveErrors > config.ErrorThreshold)
                            {
                                throw new Exception("Error threshold exceeded, shutting down");
                            }

                            T item = null;

                            try
                            {
                                if (totalInFlight > config.MaxInFlightItems || consecutiveErrors > config.ErrorThreshold)
                                {
                                    Thread.Sleep(config.TimeBetweenPolls);
                                    continue;
                                }

                                var redisValue = database.ListRightPop(inputQueueName);

                                if (!redisValue.HasValue)
                                {
                                    Thread.Sleep(config.TimeBetweenPolls);
                                    continue;
                                }

                                Interlocked.Increment(ref totalDequeued);
                                DogStatsd.Increment("total_dequeued");

                                item = JsonConvert.DeserializeObject <T>(redisValue);

                                // individual processing should not be cancelled as we have already grabbed from the queue.
                                Task.Factory.StartNew(() => { ProcessResult(item); }, CancellationToken.None, TaskCreationOptions.HideScheduler, threadPool)
                                .ContinueWith(t =>
                                {
                                    if (t.Exception == null)
                                    {
                                        Interlocked.Increment(ref totalProcessed);

                                        // ReSharper disable once AccessToDisposedClosure
                                        DogStatsd.Increment("total_processed");

                                        Interlocked.Exchange(ref consecutiveErrors, 0);
                                    }
                                    else
                                    {
                                        Interlocked.Increment(ref totalErrors);

                                        // ReSharper disable once AccessToDisposedClosure
                                        DogStatsd.Increment("total_errors");

                                        Interlocked.Increment(ref consecutiveErrors);

                                        Console.WriteLine($"Error processing {item}: {t.Exception}");
                                        attemptRetry(item);
                                    }
                                }, CancellationToken.None);
                            }
                            catch (Exception e)
                            {
                                Interlocked.Increment(ref consecutiveErrors);
                                Console.WriteLine($"Error processing from queue: {e}");
                                attemptRetry(item);
                            }
                        }

                        Console.WriteLine("Shutting down..");
                    }
                }

            DogStatsd.Dispose();
            outputStats();
        }
 public ThreadedTaskSchedulerDebugView(ThreadedTaskScheduler scheduler)
 {
     Scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
 }