C # рдореЗрдВ рдХрдиреЗрдХреНрдЯреЗрдб рдлрд┐рдХреНрд╕реНрдбрдкреВрд▓ рдХреЗ рд▓рд┐рдП рдЯреЗрд╕реНрдЯ рдЯрд╛рд╕реНрдХред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ? рдпреБрдкреАрдбреА

рдЕрджреНрдпрддрди: рдореИрдВ рдЕрдкрдиреЗ рдЧрд▓рдд рдХреЛрдб рдХреЛ рд╕рд╣реА рдХрд░рдиреЗ рдХреА рдЦреБрд╢реА рд╕реЗ рдЗрдирдХрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред "рддреНрд░реБрдЯрд┐рдпреЛрдВ рдкрд░ рдХрд╛рдо рдХрд░реЗрдВ" рдПрдХ рдЦрдВрдб рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдкреНрд░рд╛рдкреНрдд рдХреЛрдб рдФрд░ рдкреНрд░рд╛рдкреНрдд рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реБрдзрд╛рд░ рдХрд╛ рд╡рд┐рд╡рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реВрдВред

рдпрд╣ рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮреЛрдВ рдХреЗ рдмрд╛рдж рдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЕрдзрд┐рдХ рд╣реИред рдореИрдВ рдЖрдкрдХреЛ рдПрдХ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реВрдВред
рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореБрдЭреЗ Svyaznoy рдореЗрдВ рдЕрдкрдирд╛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рд╕реМрднрд╛рдЧреНрдп рдорд┐рд▓рд╛ рд╣реИред рдПрдХ рдиреЗрдЯ рдбреЗрд╡рд▓рдкрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВред рдЬрд╡рд╛рдм рдореЗрдВ, рдореБрдЭреЗ рдПрдХ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдиреЙрд▓реЗрдЬ рдЯреЗрд╕реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЧрдпрд╛ред рдореИрдВ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдирд╣реАрдВ рдХрд╣ рд╕рдХрддрд╛, рд▓реЗрдХрд┐рди, рдлрд┐рд░ рднреА, рдореИрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдордЭ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдореБрдЭреЗ рдХреИрд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП:

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЬрд╛рд╡рд╛ рдореЗрдВ рдлрд┐рдХреНрд╕реНрдбрд╣реНрд░реЗрдбрдкреВрд▓ рдХреЗ рд╕рдорд╛рди рд╕реА # рд╡рд░реНрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


рдЪреВрдВрдХрд┐ рдЯрд╛рд╕реНрдХ рдиреЗ рдпрд╣ рдирд╣реАрдВ рдмрддрд╛рдпрд╛ рдХрд┐ рдореБрдЭреЗ рдХрд┐рди рдкреНрд░рд╛рдЗрдорд┐рдЯрд┐рд╡реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЪрд╛рд╣реЗ рдореИрдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓рддрдо рдереНрд░реЗрдб рдкрд░ рдХрд░реВрдВ рдпрд╛ рдереНрд░реЗрдбрдкреВрд▓, рдЯреАрдкреАрдПрд▓, рдЖрджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ, рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдХрд╛рд░реНрдп рдореЗрдВ рд╕рдмрд╕реЗ рдмреБрдирд┐рдпрд╛рджреА рддрддреНрд╡реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИ: рдереНрд░реЗрдб, рдореИрдиреБрдЕрд▓рдПрд╕реЗрдЯрдПрд╡реЗрдВрдЯреНрд╕, рдЖрджрд┐ред рдХреБрдЫ рдШрдВрдЯреЛрдВ рдореЗрдВ рд▓рд┐рдЦрд╛, рднреЗрдЬрд╛ рдЧрдпрд╛ред рдЖрдЬ рдореИрдВрдиреЗ рдХрд╛рд░реНрдорд┐рдХ рдЕрдзрд┐рдХрд╛рд░реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╡рд╛рдм рджрд┐рдпрд╛ рдФрд░ рдЬрд╡рд╛рдм рджрд┐рдпрд╛, рдЬреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рдЧ рд░рд╣рд╛ рдерд╛: "рдпрд╣ рднреА рдЬрд░реВрд░рдд рдХреЗ рдХрд░реАрдм рдирд╣реАрдВ рд╣реИред" рдпрд╣ рдореБрдЭреЗ рд╣реИрд░рд╛рди рдХрд░ рдЧрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдХреЛрдб рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдХреЛрдИ рд╕реНрдкрд╖реНрдЯ рджреЛрд╖ рдирд╣реАрдВ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЗ рдирд┐рд░реНрдгрдп рдореЗрдВ, рдореИрдВ рдлрд┐рдХреНрд╕реНрдбрд╣реНрд░реЗрдбрдкреВрд▓ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ рддреБрд░рдВрдд рдЪреЗрддрд╛рд╡рдиреА рджреА рд╣реИ рдХрд┐, рдЙрдирдХреА рд░рд╛рдп рдореЗрдВ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддреНрд░реБрдЯрд┐рдкреВрд░реНрдг рд╣реИ, рдФрд░, рддрджрдиреБрд╕рд╛рд░, рдпрд╣ рдореЗрд░реЗ рд╡рд┐рдЪрд╛рд░ рдХреЛ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдиреЗ рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИред рдХреЛрдб рдкрд░ рдХреБрдЫ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ:



FixedThreadPool
/// <summary> ///  ,           /// . /// </summary> /// <remarks> ///     . /// </remarks> public sealed class FixedThreadPool { #region Constructors /// <summary> ///         ///  . /// </summary> /// <param name="aConcurrentTaskNumber"> ///     . /// </param> /// <param name="aLog"> ///  . /// </param> /// <param name="aPriorityLog"> ///        . /// </param> /// <exception cref="ArgumentOutOfRangeException"> ///       . /// </exception> public FixedThreadPool (int aConcurrentTaskNumber, ILog aLog = null, ILog aPriorityLog = null) { if (aConcurrentTaskNumber <= 1) { throw new ArgumentOutOfRangeException( "aConcurrentTaskNumber", "       ."); } Log = aLog; PriorityLog = aPriorityLog; mConcurrentTaskNumber = aConcurrentTaskNumber; LogMessage("  ."); Thread lTaskSchedulerThread = new Thread(TaskSchedulerLogic) {Name = " ."}; lTaskSchedulerThread.Start(); LogMessage("  ."); } #endregion #region Public methods /// <summary> ///   <paramref name="aTask"/>       /// <paramref name="aTaskPriority"/>. /// </summary> /// <param name="aTask"> ///       .. /// </param> /// <param name="aTaskPriority"> ///  . /// </param> /// <returns> /// <see langword="true"/> -      . /// <see langword="false"/> -        ,   ///     . /// </returns> /// <exception cref="ArgumentNullException"> ///         . /// </exception> public bool Execute(Task aTask, TaskPriority aTaskPriority) { if (aTask == null) { throw new ArgumentNullException( "aTask", "        ."); } LogMessage("    ."); lock (mIsStoppedLock) { if (IsStopped) { //  . LogPriority(aTaskPriority, ConsoleColor.DarkGray); //   . return false; } } //    . EnqueueTask(aTask, aTaskPriority); LogMessage("    .", ConsoleColor.DarkYellow); return true; } /// <summary> ///       ,   .  ///         . /// </summary> /// <remarks> ///             ///    <see cref="Execute"/>   <see langword="false"/>. /// ,     ,     . /// </remarks> public void Stop() { //     . lock (mIsStoppedLock) { IsStopped = true; LogMessage("  ."); } //     ,   . LogMessage( "        .", ConsoleColor.DarkRed); lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } mPoolStoppedGate.WaitOne(); LogMessage("      .", ConsoleColor.DarkRed); } #endregion #region Private properties /// <summary> /// /  ,    . /// </summary> /// <value> /// <see langword="true"/> -   ,      ///  . <see langword="false"/> -   . /// </value> /// <remarks> ///    <see cref="mIsStoppedLock"/>. /// </remarks> private bool IsStopped { get; set; } /// <summary> /// /    . /// </summary> private ILog PriorityLog { get; set; } /// <summary> /// /   . /// </summary> private ILog Log { get; set; } #endregion #region Private methods /// <summary> ///     .    . /// </summary> private void TaskSchedulerLogic() { lock (mTaskSchedulerLock) { while (true) { //     ,   mTaskSchedulerLock. Monitor.Wait(mTaskSchedulerLock); lock (mQueuedTasksLock) { lock (mIsStoppedLock) { lock (mRunningTasksLock) { if (IsStopped && !mRunningTasks.Any() && !mQueuedTasks.Any()) { LogMessage( "          ."); LogMessage(" -    ."); //      . mPoolStoppedGate.Set(); return; } } } } lock (mQueuedTasksLock) { if (!mQueuedTasks.Any()) { //   . //  . continue; } } lock (mRunningTasksLock) { if (mRunningTasks.Count >= mConcurrentTaskNumber) { //    . //  . continue; } } LogMessage( "     .", ConsoleColor.DarkRed); //       . TaskListEntry lTask = DequeueTask(); LogMessage(" -     ."); //      . lTask.Task.Finished += OnTaskFinished; //      . lock (mRunningTasksLock) { mRunningTasks.Add(lTask); } if (lTask.TaskPriority == TaskPriority.High) { //     . //          . Interlocked.Increment(ref mQueuedHighPriorityTaskCounter); } else if (lTask.TaskPriority == TaskPriority.Normal) { //     . //          HighPriorityTaskFactor. Interlocked.Add( ref mQueuedHighPriorityTaskCounter, -HighPriorityTaskFactor); } //    . lTask.Task.Execute(); LogMessage( string.Format( " -     {0}.", lTask.TaskPriority), ConsoleColor.DarkYellow); lock (mRunningTasksLock) { LogMessage( string.Format( "    {0} .", mRunningTasks.Count)); } } } } /// <summary> ///    . /// </summary> /// <param name="aSender"> /// - . /// </param> /// <param name="aEventArgs"> ///  . /// </param> private void OnTaskFinished(object aSender, EventArgs aEventArgs) { Task lSender = aSender as Task; Debug.Assert( lSender != null, "  aSender      ."); //    ,       . lSender.Finished -= OnTaskFinished; //     . lock (mRunningTasksLock) { //         . TaskListEntry lEntry = mRunningTasks.First(aEntry => aEntry.Task == lSender); mRunningTasks.Remove(lEntry); LogMessage( string.Format("   {0} .", lEntry.TaskPriority), ConsoleColor.Red); } lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } } /// <summary> ///   <paramref name="aTask"/>     . /// </summary> /// <param name="aTask"> /// ,      . /// </param> /// <param name="aTaskPriority"> ///  . /// </param> private void EnqueueTask(Task aTask, TaskPriority aTaskPriority) { TaskListEntry lEntry = new TaskListEntry(aTask, aTaskPriority); LogPriority(aTaskPriority, ConsoleColor.Green); lock (mQueuedTasksLock) { //       . mQueuedTasks.Add(lEntry); LogMessage( string.Format( "      {0}", lEntry.TaskPriority), ConsoleColor.Green); //      . LogMessage("     .", ConsoleColor.DarkRed); } lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } } /// <summary> ///         .    ///   ,   . /// </summary> /// <returns> /// ,      . /// </returns> private TaskListEntry DequeueTask() { TaskListEntry lNextTask; lock (mQueuedTasksLock) { lNextTask = FindNextTaskUsingPriorityRules(); LogPriority(lNextTask.TaskPriority, ConsoleColor.Red); LogMessage( string.Format( "       {0}.", lNextTask.TaskPriority), ConsoleColor.DarkRed); mQueuedTasks.Remove(lNextTask); } lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } return lNextTask; } /// <summary> ///       . /// </summary> /// <returns> ///     . /// </returns> /// <remarks> ///    :       ///     .  ,     ,   ///        .   ,   /// ,    ,      .   ///   ,   ,      -, ///      -  . /// </remarks> private TaskListEntry FindNextTaskUsingPriorityRules() { TaskListEntry lNextTask; lock (mQueuedTasksLock) { Debug.Assert( mQueuedTasks.Count > 0, " FindNextTaskUsingPriorityRules   ,    ."); //        . TaskPriority lNextTaskPriority = TaskPriority.High; //        . if (mQueuedTasks.All(aEntry => aEntry.TaskPriority == TaskPriority.Low)) { //        . //      . lNextTaskPriority = TaskPriority.Low; } else { //        . if (mQueuedTasks.Any( aEntry => aEntry.TaskPriority == TaskPriority.Normal) && (mQueuedTasks.All( aEntry => aEntry.TaskPriority != TaskPriority.High) || Interlocked.CompareExchange(ref mQueuedHighPriorityTaskCounter, 0, 0) >= HighPriorityTaskFactor)) { //            //         //         . //      . lNextTaskPriority = TaskPriority.Normal; } } lNextTask = mQueuedTasks.First( aEntry => aEntry.TaskPriority == lNextTaskPriority); } return lNextTask; } /// <summary> ///    . /// </summary> /// <param name="aMessage"> /// . /// </param> /// <param name="aColor"> ///  . /// </param> private void LogMessage(string aMessage, ConsoleColor aColor = ConsoleColor.Yellow) { if (Log == null) { return; } Log.WriteMessage(aMessage, aColor); } /// <summary> ///     . /// </summary> /// <param name="aTaskPriority"> ///  . /// </param> /// <param name="aColor"> ///  . /// </param> private void LogPriority(TaskPriority aTaskPriority, ConsoleColor aColor) { if (PriorityLog == null) { return; } string lPriority = aTaskPriority == TaskPriority.High ? "H" : aTaskPriority == TaskPriority.Normal ? "N" : "L"; PriorityLog.WriteMessage(lPriority, aColor); } #endregion #region Private data /// <summary> ///     ,        /// ,        ,     ///    . /// </summary> private const int HighPriorityTaskFactor = 3; /// <summary> ///     .    ///   . /// </summary> private readonly int mConcurrentTaskNumber; /// <summary> ///      <see cref="IsStopped"/>. /// </summary> private readonly object mIsStoppedLock = new object(); /// <summary> ///    . ,       ///   . /// </summary> private readonly ManualResetEvent mPoolStoppedGate = new ManualResetEvent(false); /// <summary> ///  ,     . /// </summary> /// <remarks> ///    <see cref="mQueuedTasksLock"/>. /// </remarks> private readonly IList<TaskListEntry> mQueuedTasks = new List<TaskListEntry>(); /// <summary> ///       <see cref="mQueuedTasks"/>. /// </summary> private readonly object mQueuedTasksLock = new object(); /// <summary> ///      . /// </summary> /// <remarks> ///    <see cref="mRunningTasksLock"/>. /// </remarks> private readonly IList<TaskListEntry> mRunningTasks = new List<TaskListEntry>(); /// <summary> ///     <see cref="mRunningTasks"/>. /// </summary> private readonly object mRunningTasksLock = new object(); /// <summary> ///  ,   /  . /// </summary> private readonly object mTaskSchedulerLock = new object(); /// <summary> ///     ,   .    ///        ,     ///       <see cref="HighPriorityTaskFactor"/>. /// </summary> /// <remarks> ///          /// <see cref="Interlocked"/>. /// </remarks> private int mQueuedHighPriorityTaskCounter; #endregion #region Nested type: TaskListEntry /// <summary> ///   . /// </summary> /// <remarks> ///     . /// </remarks> private struct TaskListEntry { #region Constructors /// <summary> ///          . /// </summary> /// <param name="aTask"> /// . /// </param> /// <param name="aTaskPriority"> ///  . /// </param> public TaskListEntry(Task aTask, TaskPriority aTaskPriority) { mTask = aTask; mTaskPriority = aTaskPriority; } #endregion #region Public properties /// <summary> /// . /// </summary> public Task Task { get { return mTask; } } /// <summary> ///  . /// </summary> public TaskPriority TaskPriority { get { return mTaskPriority; } } #endregion #region Private data private readonly Task mTask; private readonly TaskPriority mTaskPriority; #endregion } #endregion } 


рдХрд╛рд░реНрдп
  /// <summary> ///     <see cref="FixedThreadPool1"/>. /// </summary> public class Task { #region Constructors /// <summary> ///        <see cref="FixedThreadPool1"/> ///   . /// </summary> /// <param name="aTaskBody"> ///   . /// </param> /// <exception cref="ArgumentNullException"> ///     . /// </exception> public Task(Action aTaskBody) { if (aTaskBody == null) { throw new ArgumentNullException("aTaskBody", "    ."); } TaskBody = aTaskBody; } #endregion #region Public properties /// <summary> /// /   . /// </summary> public Action TaskBody { get; private set; } #endregion #region Events /// <summary> /// ,     . /// </summary> public event EventHandler Finished; #endregion #region Public methods /// <summary> ///   . /// </summary> public void Execute() { Thread lTaskThread = new Thread( () => { //  . TaskBody(); //    . EventHandler lFinished = Finished; if (lFinished != null) { lFinished(this, EventArgs.Empty); } }) {Name = "Task thread."}; lTaskThread.Start(); } #endregion } 


TaskPriority
 /// <summary> ///  . /// </summary> public enum TaskPriority { /// <summary> ///  . /// </summary> High = 0, /// <summary> ///  . /// </summary> Normal, /// <summary> ///  . /// </summary> Low } 



рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдореЗрдВ рддреНрд░реБрдЯрд┐


рдЖрдкрдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред рдореИрдВрдиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдпрджрд┐ рдЖрдк рд╕рд╣реА рд╕рдорд╛рдзрд╛рди рдкреНрд░рдХрд╛рд╢рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╡рд┐рд╖рдп рдмрдВрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рд╕рд┐рдлрд╛рд░рд┐рд╢реЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реВрдВрдЧрд╛ рдФрд░ рдпрд╣ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреМрди рд╕реЗ рдХреЛрдб рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдФрд░ рдХреМрди рд╕реЗ рдирд╣реАрдВ, рдФрд░ рдХреНрдпреЛрдВред

рд╕реБрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдпрд╣рд╛рдБ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рд╕рд╣реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб:

FixedThreadPool
 // : Eshva.Threading //  : FixedThreadPool.cs // GUID : 7F1EECB7-F28A-4A20-9536-26D174BCD437 // : Mike Eshva (mike@eshva.ru) //  : 04.06.2012 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; namespace Eshva.Threading.Framework { /// <summary> ///  ,           /// . /// </summary> /// <remarks> ///     . /// </remarks> public sealed class FixedThreadPool { #region Constructors /// <summary> ///         ///  . /// </summary> /// <param name="aConcurrentTaskNumber"> ///     . /// </param> /// <param name="aLog"> ///  . /// </param> /// <param name="aPriorityLog"> ///        . /// </param> /// <exception cref="ArgumentOutOfRangeException"> ///       . /// </exception> public FixedThreadPool (int aConcurrentTaskNumber, ILog aLog = null, ILog aPriorityLog = null) { if (aConcurrentTaskNumber <= 1) { throw new ArgumentOutOfRangeException( "aConcurrentTaskNumber", "       ."); } Log = aLog; PriorityLog = aPriorityLog; for (int lThreadIndex = 0; lThreadIndex < aConcurrentTaskNumber; lThreadIndex++) { string lThreadName = string.Format("Task thread #{0}", lThreadIndex); Thread lTaskThread = new Thread(TaskThreadLogic) {Name = lThreadName}; lTaskThread.Start(); } } #endregion #region Public methods /// <summary> ///   <paramref name="aTask"/>       /// <paramref name="aTaskPriority"/>. /// </summary> /// <param name="aTask"> ///       .. /// </param> /// <param name="aTaskPriority"> ///  . /// </param> /// <returns> /// <see langword="true"/> -      . /// <see langword="false"/> -        ,   ///     . /// </returns> /// <exception cref="ArgumentNullException"> ///         . /// </exception> public bool Execute(Task aTask, TaskPriority aTaskPriority) { if (aTask == null) { throw new ArgumentNullException( "aTask", "        ."); } LogMessage("    ."); lock (mIsStoppedLock) { if (IsStopped) { //  . LogPriority(aTaskPriority, ConsoleColor.DarkGray); //   . return false; } } //    . EnqueueTask(aTask, aTaskPriority); LogMessage("    .", ConsoleColor.DarkYellow); return true; } /// <summary> ///       ,   .  ///         . /// </summary> /// <remarks> ///             ///    <see cref="Execute"/>   <see langword="false"/>. /// ,     ,     . /// </remarks> public void Stop() { //     . lock (mIsStoppedLock) { IsStopped = true; LogMessage("  ."); } //     ,   . LogMessage( "        .", ConsoleColor.DarkRed); lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.PulseAll(mTaskSchedulerLock); } mPoolStoppedGate.WaitOne(); LogMessage("      .", ConsoleColor.DarkRed); } #endregion #region Private properties /// <summary> /// /  ,    . /// </summary> /// <value> /// <see langword="true"/> -   ,      ///  . <see langword="false"/> -   . /// </value> /// <remarks> ///    <see cref="mIsStoppedLock"/>. /// </remarks> private bool IsStopped { get; set; } /// <summary> /// /    . /// </summary> private ILog PriorityLog { get; set; } /// <summary> /// /   . /// </summary> private ILog Log { get; set; } #endregion #region Private methods private void TaskThreadLogic() { lock (mTaskSchedulerLock) { while (true) { //     ,   mTaskSchedulerLock. Monitor.Wait(mTaskSchedulerLock); lock (mQueuedTasksLock) { if (!mQueuedTasks.Any()) { lock (mIsStoppedLock) { if (IsStopped) { LogMessage( "          ."); LogMessage(" -    ."); //      . mPoolStoppedGate.Set(); return; } } //    ,       . //    . continue; } } LogMessage( "     .", ConsoleColor.DarkRed); //       . TaskListEntry lTask = DequeueTask(); LogMessage(" -     ."); switch (lTask.TaskPriority) { case TaskPriority.High: Interlocked.Increment(ref mQueuedHighPriorityTaskCounter); break; case TaskPriority.Normal: Interlocked.Add( ref mQueuedHighPriorityTaskCounter, -HighPriorityTaskFactor); break; } //    . lTask.Task.Execute(); LogMessage( string.Format( " -     {0}.", lTask.TaskPriority), ConsoleColor.DarkYellow); lock (mQueuedTasksLock) { lock (mIsStoppedLock) { if (IsStopped && !mQueuedTasks.Any()) { LogMessage( "          ."); LogMessage(" -    ."); //      . mPoolStoppedGate.Set(); return; } } } } } } /// <summary> ///   <paramref name="aTask"/>     . /// </summary> /// <param name="aTask"> /// ,      . /// </param> /// <param name="aTaskPriority"> ///  . /// </param> private void EnqueueTask(Task aTask, TaskPriority aTaskPriority) { TaskListEntry lEntry = new TaskListEntry(aTask, aTaskPriority); LogPriority(aTaskPriority, ConsoleColor.Green); lock (mQueuedTasksLock) { //       . mQueuedTasks.Add(lEntry); LogMessage( string.Format( "      {0}", lEntry.TaskPriority), ConsoleColor.Green); //      . LogMessage("     .", ConsoleColor.DarkRed); } lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } } /// <summary> ///         .    ///   ,   . /// </summary> /// <returns> /// ,      . /// </returns> private TaskListEntry DequeueTask() { TaskListEntry lNextTask; lock (mQueuedTasksLock) { lNextTask = FindNextTaskUsingPriorityRules(); LogPriority(lNextTask.TaskPriority, ConsoleColor.Red); LogMessage( string.Format( "       {0}.", lNextTask.TaskPriority), ConsoleColor.DarkRed); mQueuedTasks.Remove(lNextTask); } lock (mTaskSchedulerLock) { //        mTaskSchedulerLock. Monitor.Pulse(mTaskSchedulerLock); } return lNextTask; } /// <summary> ///       . /// </summary> /// <returns> ///     . /// </returns> /// <remarks> ///    :       ///     .  ,     ,   ///        .   ,   /// ,    ,      .   ///   ,   ,      -, ///      -  . /// </remarks> private TaskListEntry FindNextTaskUsingPriorityRules() { TaskListEntry lNextTask; lock (mQueuedTasksLock) { Debug.Assert( mQueuedTasks.Count > 0, " FindNextTaskUsingPriorityRules   ,    ."); //        . TaskPriority lNextTaskPriority = TaskPriority.High; //        . if (mQueuedTasks.All(aEntry => aEntry.TaskPriority == TaskPriority.Low)) { //        . //      . lNextTaskPriority = TaskPriority.Low; } else { //        . if (mQueuedTasks.Any( aEntry => aEntry.TaskPriority == TaskPriority.Normal) && (mQueuedTasks.All( aEntry => aEntry.TaskPriority != TaskPriority.High) || Interlocked.CompareExchange(ref mQueuedHighPriorityTaskCounter, 0, 0) >= HighPriorityTaskFactor)) { //            //         //         . //      . lNextTaskPriority = TaskPriority.Normal; } } lNextTask = mQueuedTasks.First( aEntry => aEntry.TaskPriority == lNextTaskPriority); } return lNextTask; } /// <summary> ///    . /// </summary> /// <param name="aMessage"> /// . /// </param> /// <param name="aColor"> ///  . /// </param> private void LogMessage(string aMessage, ConsoleColor aColor = ConsoleColor.Yellow) { if (Log == null) { return; } Log.WriteMessage(aMessage, aColor); } /// <summary> ///     . /// </summary> /// <param name="aTaskPriority"> ///  . /// </param> /// <param name="aColor"> ///  . /// </param> private void LogPriority(TaskPriority aTaskPriority, ConsoleColor aColor) { if (PriorityLog == null) { return; } string lPriority = aTaskPriority == TaskPriority.High ? "H" : aTaskPriority == TaskPriority.Normal ? "N" : "L"; PriorityLog.WriteMessage(lPriority, aColor); } #endregion #region Private data /// <summary> ///     ,        /// ,        ,     ///    . /// </summary> private const int HighPriorityTaskFactor = 3; /// <summary> ///      <see cref="IsStopped"/>. /// </summary> private readonly object mIsStoppedLock = new object(); /// <summary> ///    . ,       ///   . /// </summary> private readonly ManualResetEvent mPoolStoppedGate = new ManualResetEvent(false); /// <summary> ///  ,     . /// </summary> /// <remarks> ///    <see cref="mQueuedTasksLock"/>. /// </remarks> private readonly IList<TaskListEntry> mQueuedTasks = new List<TaskListEntry>(); /// <summary> ///       <see cref="mQueuedTasks"/>. /// </summary> private readonly object mQueuedTasksLock = new object(); /// <summary> ///  ,   /  . /// </summary> private readonly object mTaskSchedulerLock = new object(); /// <summary> ///     ,   .    ///        ,     ///       <see cref="HighPriorityTaskFactor"/>. /// </summary> /// <remarks> ///          /// <see cref="Interlocked"/>. /// </remarks> private int mQueuedHighPriorityTaskCounter; #endregion #region Nested type: TaskListEntry /// <summary> ///   . /// </summary> /// <remarks> ///     . /// </remarks> private struct TaskListEntry { #region Constructors /// <summary> ///          . /// </summary> /// <param name="aTask"> /// . /// </param> /// <param name="aTaskPriority"> ///  . /// </param> public TaskListEntry(Task aTask, TaskPriority aTaskPriority) { mTask = aTask; mTaskPriority = aTaskPriority; } #endregion #region Public properties /// <summary> /// . /// </summary> public Task Task { get { return mTask; } } /// <summary> ///  . /// </summary> public TaskPriority TaskPriority { get { return mTaskPriority; } } #endregion #region Private data private readonly Task mTask; private readonly TaskPriority mTaskPriority; #endregion } #endregion } } 


рдХрд╛рд░реНрдп
 // : Eshva.Threading //  : Task.cs // GUID : 292467E7-4816-4407-BB9B-3309D13C8614 // : Mike Eshva (mike@eshva.ru) //  : 04.06.2012 using System; namespace Eshva.Threading.Framework { /// <summary> ///     <see cref="FixedThreadPool"/>. /// </summary> public class Task { #region Constructors /// <summary> ///        <see cref="FixedThreadPool"/> ///   . /// </summary> /// <param name="aTaskBody"> ///   . /// </param> /// <exception cref="ArgumentNullException"> ///     . /// </exception> public Task(Action aTaskBody) { if (aTaskBody == null) { throw new ArgumentNullException("aTaskBody", "    ."); } TaskBody = aTaskBody; } #endregion #region Public methods /// <summary> ///   . /// </summary> public void Execute() { TaskBody(); } #endregion #region Private properties /// <summary> /// /   . /// </summary> private Action TaskBody { get; set; } #endregion } } 

Source: https://habr.com/ru/post/In145551/


All Articles