标签:
在开发中遇到过这样的需求,主线程中开启多个子线程来处理数据以提高效率,待所有的子线程执行完成任务后,主线程继续完成后续的操作。一番思考后,思路出来了,我的做法是定义一个全局整型的静态变量,每个子线程完成任务后变量加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();
}
}
}
}
运行结果:
标签:
原文地址:http://www.cnblogs.com/kaixiangbb/p/3706669.html