C# 实时线程监控类的改进

版权声明:未经允许,不可转载。 https://blog.csdn.net/zhengxu25689/article/details/82892498

        这篇文章之所以称之为实时线程监控类的改进,是因为在先前写过一篇关于《C# 一个线程实时监控类 》,是对这个类的一个改进。

PS:这里说明下,关于《C# 一个线程实时监控类》为何要自己去实现,而不是直接使用C#本身的类库Task,可以参考我的另一篇关于《C#中如果正确使用线程Task类和Thread类》,文章中说明了问题的原因。

      这篇文章即然是为了实现实时线程监控类,所以在实现类是将Thread类进行封装,以便于使用上的尽可能方便和简洁(达到Task的使用效果)以及保证线程本身的实时性强(不受硬件CPU问题)。

在实现过程中通过两个类来完成:

  • AutomateThread:对线程类Thread的封装。

  1. StartNew:新建并立即启动一个后台线程, 不等待线程完成。
           /// <summary>
            /// Starts the new thread.
            /// </summary>
            /// <param name="start">The start.</param>
            /// <param name="priority">The priority.</param>
            /// <returns>Thread.</returns>
            public static Thread StartNew(ThreadStart start, ThreadPriority priority = ThreadPriority.Normal)
            {
                Thread t = new Thread(start);
    
                t.IsBackground = true;
                t.Priority = priority;
                t.Start();
    
                return t;
            }
  2. TasksExecuteAsyn:新建并立即启动多个后台线程, 等待所有线程完成。
          /// <summary>
            /// Taskses the execute asyn.
            /// </summary>
            /// <param name="starts">The starts.</param>
            public static void TasksExecuteAsyn(params ThreadStart[] starts)
            {
                int  count=starts.Length;
                ManualResetTask task = new ManualResetTask(count);
             
                for (int i = 0; i < starts.Length; i++)
                {
                    ThreadStart run = starts[i];
                    StartNew(new ThreadStart(() =>
                    {
                        run();
                        task.NotifiyThreadCompleted();
                    }));
                }
    
                task.Wait();
            }

    未改进代码如下:

            /// <summary>
            /// Taskses the execute asyn.
            /// </summary>
            /// <param name="starts">The starts.</param>
            public static void TasksExecuteAsyn(params ThreadStart[] starts)
            {
                Thread[] threads = new Thread[starts.Length];
    
                for (int i = 0; i < starts.Length; i++)
                {
                    threads[i] = StartNew(starts[i]);
                }
    
                WaitAll(threads);
            }
    
            /// <summary>
            /// Waits all.
            /// </summary>
            /// <param name="threads">The threads.</param>
            public static void WaitAll(params Thread[] threads)
            {
                foreach (Thread t in threads)
                {
                    while (t != null && t.IsAlive)
                    {
                        Thread.Sleep(1);
                    }
                }
            }
  3. Monitor:新建并立即启动一个后台线程,并监控线程是否在指定的时间内完成结束。

     

   /// <summary>
        /// Monitors the specified period.
        /// </summary>
        /// <param name="period">The period.</param>
        /// <param name="start">The start.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool Monitor(int period, ThreadStart start)
        {
            ManualResetTask task = new ManualResetTask(1);
            StartNew(new ThreadStart(() =>
            {
                start();
                task.NotifiyThreadCompleted();
            }));

            return !task.Wait(period);      
        }

    未改进前代码如下:

       /// <summary>
        /// Monitors the specified period.
        /// </summary>
        /// <param name="period">The period.</param>
        /// <param name="start">The start.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool Monitor(int period, ThreadStart start)
        {
            Tickwatch sw = Tickwatch.StartNew();
            Thread t = AutomateThread.StartNew(start);

            while (sw.ElapsedMilliseconds < period)
            {
                if (!t.IsAlive)
                {
                    return false;
                }

                AutomateThread.Sleep(1);
            }

            return true;
        }
  • ManualResetTask:监控多个AutomateThread线程等待执行完成。

应该可以注意到,ManualResetTask类的实现主要是改进AutomateThread等待线程执行完成的实现代码作了改进。

未改进版本: 采用Thread.Sleep(),循环等待所有启动的线程,直到所有线程完成为止。采用Thread.Sleep()方法是根据CPUxg程时间片轮循的机制进行判断,时间较不准确。目前在双核CPU情况下,Thread.Sleep(1)大约时间精度为15ms。

改进版本:使用ManualResetTask,主要采用ManualResetEvent,通过事件通知来完成,时间的精度比Thread.Sleep(1)高,且较为稳定。关于ManualResetEvent,可以自行查看MSDN资料。

AutomateThread实现代码如下:

// ***********************************************************************
// Assembly         : Common.Class
// Author           : maojun.zheng
// Created          : 2017-05-25
//
// Last Modified By : maojun.zheng
// Last Modified On : 2018-03-06
// ***********************************************************************
// <copyright file="AutomateThread.cs" company="">
//     Copyright (c) . All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************

using System.Collections.Generic;
using System.Threading;

/// <summary>
/// The Common namespace.
/// </summary>
namespace Common.Class
{
    /// <summary>
    /// Class AutomateThread.
    /// </summary>
    public class AutomateThread
    {
        /// <summary>
        /// Starts the new.
        /// </summary>
        /// <param name="start">The start.</param>
        /// <param name="priority">The priority.</param>
        /// <returns>Thread.</returns>
        public static Thread StartNew(ThreadStart start, ThreadPriority priority = ThreadPriority.Normal)
        {
            Thread t = new Thread(start);

            t.IsBackground = true; //这里简单说明下:设置线程为后台线程,不清楚的可自行查阅下
            t.Priority = priority;
            t.Start();

            return t;
        }

         /// <summary>
        /// Taskses the execute asyn.
        /// </summary>
        /// <param name="starts">The starts.</param>
        public static void TasksExecuteAsyn(params ThreadStart[] starts)
        {
            int  count=starts.Length;
            ManualResetTask task = new ManualResetTask(count);
         
            for (int i = 0; i < starts.Length; i++)
            {
                ThreadStart run = starts[i];
                StartNew(new ThreadStart(() =>
                {
                    run();
                    task.NotifiyThreadCompleted();
                }));
            }

            task.Wait();
        }
        /// <summary>
        /// Monitors the specified period.
        /// </summary>
        /// <param name="period">The period.</param>
        /// <param name="start">The start.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool Monitor(int period, ThreadStart start)
        {
            ManualResetTask task = new ManualResetTask(1);
            StartNew(new ThreadStart(() =>
            {
                start();
                task.NotifiyThreadCompleted();
            }));

            return !task.Wait(period);      
        }
    }
}

ManualResetTask代码实现如下:

// ***********************************************************************
// Assembly         : Common.Class
// Author           : maojun.zheng
// Created          : 2018-09-28
//
// Last Modified By : maojun.zheng
// Last Modified On : 2018-09-19
// ***********************************************************************
// <copyright file="ManualResetTask.cs" company="">
//     Copyright (c) . All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// The Class namespace.
/// </summary>
namespace Common.Class
{
    /// <summary>
    /// Class ManualResetTask.
    /// </summary>
    public class ManualResetTask
    {
        /// <summary>
        /// The thread count
        /// </summary>
        private readonly int threadCount;
        /// <summary>
        /// The count
        /// </summary>
        private int count ;
        /// <summary>
        /// The root
        /// </summary>
        private object root;
        /// <summary>
        /// Initializes a new instance of the <see cref="ManualResetTask"/> class.
        /// </summary>
        /// <param name="threadCount">The thread count.</param>
        public ManualResetTask(int threadCount)
        {
            this.threadCount = threadCount;
            this.count = 0;
            this.resetEvent = new ManualResetEvent(false);
            this.root = new object();
        }

        /// <summary>
        /// The reset event
        /// </summary>
        private ManualResetEvent resetEvent;


        /// <summary>
        /// Notifiys the thread completed.
        /// </summary>
        public void NotifiyThreadCompleted()
        {
            lock(this.root)
            {
                this.count++;
                if (count >= this.threadCount)
                {
                    this.resetEvent.Set();
                }
            }

        }

        /// <summary>
        /// Waits this instance.
        /// </summary>
        public void Wait()
        {           
            this.resetEvent.WaitOne();
        }

        /// <summary>
        /// Waits the specified milliseconds timeout.
        /// </summary>
        /// <param name="millisecondsTimeout">The milliseconds timeout.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public bool Wait(int millisecondsTimeout)
        {
            return this.resetEvent.WaitOne(millisecondsTimeout);
        }
    }

}

猜你喜欢

转载自blog.csdn.net/zhengxu25689/article/details/82892498
今日推荐