关于线程间通信

  在开发中遇到过这样的需求,主线程中开启多个子线程来处理数据以提高效率,待所有的子线程执行完成任务后,主线程继续完成后续的操作。一番思考后,思路出来了,我的做法是定义一个全局整型的静态变量,每个子线程完成任务后变量加1。主线程里有一个while死循环,每次循环判断这个变量的值,如果值为开启的线程数则表示所有子线程已经完成了任务,然后跳出循环继续执行后续的操作。逻辑上来看这是没有任何问题的,于是很快就完成了编码运行测试。结果自然和预料中的一样没啥问题。

  运行过程中发现cpu使用率很高,如果执行的时间过长总能感觉到风扇转的很厉害,很担心会吧自己的本本烧坏。于是想到了优化代码,可是如何下手从哪里下手呢,思考良久想到了一个很二的办法,在循环里加了句Thread.Slee()。这样,每次循环后让主线程睡眠一段时间的方法来降低循环cpu的高使用率。这样优化代码,运行了一段时间。但也没和之前进行过比较,效率是高了还是低了无所知晓,心里总在嘀咕这样的代码看着很是别扭。尽管没有几行的代码,反正看着就是不舒服、不顺眼,于是又有了优化的念头。这次的优化不再是自己苦思冥想,应该百度一下,看人家是如何实现的。

  一番搜索后,终于找到了关键字“ManualResetEvent”,然后就是MSDN查阅相关文档,以下为练习的代码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;



namespace ManualResetEventTest

{

    class Program

    {

        static void Main(string[] args)

        {

            ManualResetEventContext[] contexts = new ManualResetEventContext[5];

            ManualResetEvent[] manualResetEvents = new ManualResetEvent[5];

            for (int i = 0; i < 5; i++)

            {

                ManualResetEvent e = new ManualResetEvent(false);

                manualResetEvents[i] = e;

                contexts[i] = new ManualResetEventContext(e, doSomeThing) { ID = i };

                ThreadPool.QueueUserWorkItem(contexts[i].Invoke, contexts[i]);

            }

            WaitHandle.WaitAll(manualResetEvents);

            Console.WriteLine("所有子线程执行完成");

            Console.Read();

        }



        static void doSomeThing(object state)

        {

            ManualResetEventContext context = state as ManualResetEventContext;

            //do...

            Thread.Sleep(1000*60);

            Console.WriteLine(string.Format("第{0}个子线程执行完成", context.ID));

        }

    }



    public class ManualResetEventContext

    {

        public int ID { get; set; }

        public ManualResetEvent ManualResetEvent { get; set; }

        private WaitCallback _callback;



        public ManualResetEventContext(ManualResetEvent manualResetEvent, WaitCallback callback)

        {

            this.ManualResetEvent = manualResetEvent;

            this._callback = callback;

        }



        public void Invoke(object state)

        {

            try

            {

                _callback(state);

            }

            finally 

            {

                //子线程操作完成后必须调用此方法

                ManualResetEvent.Set();

            }

        }

    }

}
运行结果:
关于线程间通信
 
  

  

你可能感兴趣的:(线程间通信)