/// <summary>
        /// Run a variation of the pipeline that uses a user-specified number of tasks for the filter stage.
        /// </summary>
        /// <param name="fileNames">List of image file names in source directory</param>
        /// <param name="sourceDir">Name of directory of source images</param>
        /// <param name="queueLength">Length of image queue</param>
        /// <param name="displayFn">Display action</param>
        /// <param name="cts">Cancellation token</param>
        /// <param name="filterTaskCount">Number of filter tasks</param>
        static void RunLoadBalancedPipeline(IEnumerable <string> fileNames, string sourceDir, int queueLength, Action <ImageInfo> displayFn,
                                            CancellationTokenSource cts, int filterTaskCount)
        {
            // Create data pipes
            var originalImages            = new BlockingCollection <ImageInfo>(queueLength);
            var thumbnailImages           = new BlockingCollection <ImageInfo>(queueLength);
            var filteredImageMultiplexer  = new BlockingMultiplexer <ImageInfo>(info => info.SequenceNumber, 0, queueLength);
            var filteredImagesCollections = (BlockingCollection <ImageInfo>[])Array.CreateInstance(
                typeof(BlockingCollection <ImageInfo>), filterTaskCount);

            try
            {
                // Start pipelined tasks
                Action <ImageInfo> updateStatisticsFn = info =>
                {
                    info.QueueCount1 = originalImages.Count();
                    info.QueueCount2 = thumbnailImages.Count();
                    info.QueueCount3 = filteredImageMultiplexer.Count;
                };
                const TaskCreationOptions options = TaskCreationOptions.LongRunning;
                var    f      = new TaskFactory(CancellationToken.None, options, TaskContinuationOptions.None, TaskScheduler.Default);
                Task[] tasks  = (Task[])Array.CreateInstance(typeof(Task), filterTaskCount + 3);
                int    taskId = 0;

                tasks[taskId++] = f.StartNew(() =>
                                             LoadPipelinedImages(fileNames, sourceDir, originalImages, cts));

                tasks[taskId++] = f.StartNew(() =>
                                             ScalePipelinedImages(originalImages, thumbnailImages, cts));

                for (int i = 0; i < filterTaskCount; i++)
                {
                    var tmp = i;
                    filteredImagesCollections[tmp] = filteredImageMultiplexer.GetProducerQueue();
                    tasks[taskId++] = f.StartNew(() => FilterPipelinedImages(thumbnailImages, filteredImagesCollections[tmp], cts));
                }

                tasks[taskId++] = f.StartNew(() =>
                                             DisplayPipelinedImages(filteredImageMultiplexer.GetConsumingEnumerable(), displayFn,
                                                                    updateStatisticsFn, cts));

                Task.WaitAll(tasks);
            }
            finally
            {
                // there might be cleanup in the case of cancellation or an exception.
                DisposeImagesInQueue(originalImages);
                DisposeImagesInQueue(thumbnailImages);
                foreach (var filteredImages in filteredImagesCollections)
                {
                    DisposeImagesInQueue(filteredImages);
                }
                foreach (var info in filteredImageMultiplexer.GetCleanupEnumerable())
                {
                    info.Dispose();
                }
            }
        }
Example #2
0
        /// <summary>
        /// Run a pipeline that uses a user-specified number of tasks for the filter stage.
        /// </summary>
        /// <param name="fileNames">List of image file names in source directory</param>
        /// <param name="sourceDir">Name of directory of source images</param>
        /// <param name="queueLength">Length of image queue</param>
        /// <param name="cts">Cancellation token</param>
        /// <param name="filterTaskCount">Number of filter tasks</param>
        public static void RunPipeline(IEnumerable <string> fileNames, string sourceDir, int queueLength,
                                       CancellationTokenSource token, int filterTaskCount)
        {
            using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(token.Token))
            {
                // Create data pipes
                var originalImages           = new BlockingCollection <ImageInfo>(queueLength);
                var thumbnailImages          = new BlockingCollection <ImageInfo>(queueLength);
                var filteredImageMultiplexer =
                    new BlockingMultiplexer <ImageInfo>(info => info.SequenceNumber, 0, queueLength);
                var filteredImagesCollections = (BlockingCollection <ImageInfo>[])Array.CreateInstance(
                    typeof(BlockingCollection <ImageInfo>), filterTaskCount);

                try
                {
                    const TaskCreationOptions options = TaskCreationOptions.LongRunning;
                    var factory = new TaskFactory(CancellationToken.None, options, TaskContinuationOptions.None,
                                                  TaskScheduler.Default);
                    Task[] tasks  = (Task[])Array.CreateInstance(typeof(Task), filterTaskCount + 3);
                    int    taskId = 0;

                    tasks[taskId++] = factory.StartNew(() =>
                                                       PipelinePhases.LoadPipelinedImages(fileNames, sourceDir, originalImages, cts));

                    tasks[taskId++] = factory.StartNew(() =>
                                                       PipelinePhases.ScalePipelinedImages(originalImages, thumbnailImages, cts));

                    for (int i = 0; i < filterTaskCount; i++)
                    {
                        var tmp = i;
                        filteredImagesCollections[tmp] =
                            filteredImageMultiplexer.GetProducerQueue();
                        tasks[taskId++] = factory.StartNew(() =>
                                                           PipelinePhases.FilterPipelinedImages(thumbnailImages, filteredImagesCollections[tmp], cts));
                    }

                    tasks[taskId++] = factory.StartNew(() =>
                                                       PipelinePhases.SavePipelinedImages(filteredImageMultiplexer.GetConsumingEnumerable(), cts));

                    Task.WaitAll(tasks);
                }
                finally
                {
                    // there might be cleanup in the case of cancellation or an exception.
                    DisposeImagesInQueue(originalImages);
                    DisposeImagesInQueue(thumbnailImages);
                    foreach (var filteredImages in filteredImagesCollections)
                    {
                        DisposeImagesInQueue(filteredImages);
                    }
                    foreach (var info in filteredImageMultiplexer.GetCleanupEnumerable())
                    {
                        info.Dispose();
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Run a variation of the pipeline that uses a user-specified number of tasks for the filter stage.
        /// </summary>
        /// <param name="fileNames">List of image file names in source directory</param>
        /// <param name="sourceDir">Name of directory of source images</param>
        /// <param name="queueLength">Length of image queue</param>
        /// <param name="displayFn">Display action</param>
        /// <param name="cts">Cancellation token</param>
        /// <param name="filterTaskCount">Number of filter tasks</param>
        static void RunLoadBalancedPipeline(IEnumerable<string> fileNames, string sourceDir, int queueLength, Action<ImageInfo> displayFn,
            CancellationTokenSource cts, int filterTaskCount)
        {
            // Create data pipes 
            var originalImages = new BlockingCollection<ImageInfo>(queueLength);
            var thumbnailImages = new BlockingCollection<ImageInfo>(queueLength);
            var filteredImageMultiplexer = new BlockingMultiplexer<ImageInfo>(info => info.SequenceNumber, 0, queueLength);
            var filteredImagesCollections = (BlockingCollection<ImageInfo>[])Array.CreateInstance(
                                   typeof(BlockingCollection<ImageInfo>), filterTaskCount);

            try
            {
                // Start pipelined tasks
                Action<ImageInfo> updateStatisticsFn = info =>
                {
                    info.QueueCount1 = originalImages.Count();
                    info.QueueCount2 = thumbnailImages.Count();
                    info.QueueCount3 = filteredImageMultiplexer.Count;
                };
                const TaskCreationOptions options = TaskCreationOptions.LongRunning;
                var f = new TaskFactory(CancellationToken.None, options, TaskContinuationOptions.None, TaskScheduler.Default);
                Task[] tasks = (Task[])Array.CreateInstance(typeof(Task), filterTaskCount + 3);
                int taskId = 0;

                tasks[taskId++] = f.StartNew(() =>
                      LoadPipelinedImages(fileNames, sourceDir, originalImages, cts));

                tasks[taskId++] = f.StartNew(() =>
                      ScalePipelinedImages(originalImages, thumbnailImages, cts));

                for (int i = 0; i < filterTaskCount; i++)
                {
                    var tmp = i;
                    filteredImagesCollections[tmp] = filteredImageMultiplexer.GetProducerQueue();
                    tasks[taskId++] = f.StartNew(() => FilterPipelinedImages(thumbnailImages, filteredImagesCollections[tmp], cts));
                }

                tasks[taskId++] = f.StartNew(() =>
                      DisplayPipelinedImages(filteredImageMultiplexer.GetConsumingEnumerable(), displayFn, 
                                             updateStatisticsFn, cts));

                Task.WaitAll(tasks);
            }
            finally
            {
                // there might be cleanup in the case of cancellation or an exception.
                DisposeImagesInQueue(originalImages);
                DisposeImagesInQueue(thumbnailImages);
                foreach (var filteredImages in filteredImagesCollections)
                    DisposeImagesInQueue(filteredImages);
                foreach (var info in filteredImageMultiplexer.GetCleanupEnumerable())
                    info.Dispose();
            }
        }