• C#任务调度——LimitedConcurrencyLevelTaskScheduler


    • 这是参考大佬分享的代码写的有问题请提出指正,谢谢。
    using Serilog;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace TaskManager
    {
        class TaskFactoryMananger
        {
        //USE
            public static void Run()
            {
    
                try
                {
                    while (true)
                    {
                        LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(10);
                        TaskFactory factory = new TaskFactory(lcts);
                        Task[] spiderTask = new Task[] {
                            factory.StartNew(() =>
                            {
                                Log.Logger.Information("{0} Start on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);     
                                Log.Logger.Information("{0} Finish  on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);
                            }),
                            factory.StartNew(() =>
                            {
                                Thread.Sleep(TimeSpan.FromSeconds(3));
                                Log.Logger.Information("{0} Start on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
                                Log.Logger.Information("{0} Finish  on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
                            }),
                            factory.StartNew(() =>
                            {
                                Thread.Sleep(TimeSpan.FromSeconds(5));
                                Log.Logger.Information("{0} Start on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
                                Log.Logger.Information("{0} Finish  on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
                            })
                            };
                        Task.WaitAll(spiderTask);
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }
                }
                catch (AggregateException ex)
                {
                    foreach (Exception inner in ex.InnerExceptions)
                    {
                        Log.Logger.Error(inner.Message);
                    }
                }
            }
    
            /// <summary>
            /// Provides a task scheduler that ensures a maximum concurrency level while
            /// running on top of the ThreadPool.
            /// </summary>
            public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
            {
                /// <summary>Whether the current thread is processing work items.</summary>
                [ThreadStatic]
                private static bool _currentThreadIsProcessingItems;
                /// <summary>The list of tasks to be executed.</summary>
                private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
                /// <summary>The maximum concurrency level allowed by this scheduler.</summary>
                private readonly int _maxDegreeOfParallelism;
                /// <summary>Whether the scheduler is currently processing work items.</summary>
                private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
    
                /// <summary>
                /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
                /// specified degree of parallelism.
                /// </summary>
                /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
                public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
                {
                    if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
                    _maxDegreeOfParallelism = maxDegreeOfParallelism;
                }
    
                /// <summary>Queues a task to the scheduler.</summary>
                /// <param name="task">The task to be queued.</param>
                protected sealed override void QueueTask(Task task)
                {
                    // Add the task to the list of tasks to be processed.  If there aren't enough
                    // delegates currently queued or running to process tasks, schedule another.
                    lock (_tasks)
                    {
                        _tasks.AddLast(task);
                        if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
                        {
                            ++_delegatesQueuedOrRunning;
                            NotifyThreadPoolOfPendingWork();
                        }
                    }
                }
    
                /// <summary>
                /// Informs the ThreadPool that there's work to be executed for this scheduler.
                /// </summary>
                private void NotifyThreadPoolOfPendingWork()
                {
                    ThreadPool.UnsafeQueueUserWorkItem(_ =>
                    {
                        // Note that the current thread is now processing work items.
                        // This is necessary to enable inlining of tasks into this thread.
                        _currentThreadIsProcessingItems = true;
                        try
                        {
                            // Process all available items in the queue.
                            while (true)
                            {
                                Task item;
                                lock (_tasks)
                                {
                                    // When there are no more items to be processed,
                                    // note that we're done processing, and get out.
                                    if (_tasks.Count == 0)
                                    {
                                        --_delegatesQueuedOrRunning;
                                        break;
                                    }
    
                                    // Get the next item from the queue
                                    item = _tasks.First.Value;
                                    _tasks.RemoveFirst();
                                }
    
                                // Execute the task we pulled out of the queue
                                base.TryExecuteTask(item);
                            }
                        }
                        // We're done processing items on the current thread
                        finally { _currentThreadIsProcessingItems = false; }
                    }, null);
                }
    
                /// <summary>Attempts to execute the specified task on the current thread.</summary>
                /// <param name="task">The task to be executed.</param>
                /// <param name="taskWasPreviouslyQueued"></param>
                /// <returns>Whether the task could be executed on the current thread.</returns>
                protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
                {
                    // If this thread isn't already processing a task, we don't support inlining
                    if (!_currentThreadIsProcessingItems) return false;
    
                    // If the task was previously queued, remove it from the queue
                    if (taskWasPreviouslyQueued) TryDequeue(task);
    
                    // Try to run the task.
                    return base.TryExecuteTask(task);
                }
    
                /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
                /// <param name="task">The task to be removed.</param>
                /// <returns>Whether the task could be found and removed.</returns>
                protected sealed override bool TryDequeue(Task task)
                {
                    lock (_tasks) return _tasks.Remove(task);
                }
    
                /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
                public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
    
                /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
                /// <returns>An enumerable of the tasks currently scheduled.</returns>
                protected sealed override IEnumerable<Task> GetScheduledTasks()
                {
                    bool lockTaken = false;
                    try
                    {
                        Monitor.TryEnter(_tasks, ref lockTaken);
                        if (lockTaken) return _tasks.ToArray();
                        else throw new NotSupportedException();
                    }
                    finally
                    {
                        if (lockTaken) Monitor.Exit(_tasks);
                    }
                }
            }
        }
    }
    
    
  • 相关阅读:
    Python之字典
    Python之模块
    Python之字符串格式化
    结束循环
    循环
    C语言static和局部变量
    C static extern和全局变量
    extern static和函数
    C语言typedef
    C语言之文件包含
  • 原文地址:https://www.cnblogs.com/TTonly/p/10349916.html
Copyright © 2020-2023  润新知