[C#]『CountdownEvent』任务并行库使用小计

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定。 CountdownEvent  专门用于以下情况:您必须使用 ManualResetEvent 或 ManualResetEventSlim,并且必须在用信号通知事件之前手动递减一个变量。 例如,在分叉/联接方案中,您可以只创建一个信号计数为 5 的 CountdownEvent,然后在线程池上启动五个工作项,并且让每个工作项在完成时调用 Signal。每次调用 Signal 时,信号计数都会递减 1。 在主线程上,对 Wait 的调用将会阻塞,直至信号计数为零。

CountdownEvent  具有这些附加功能:

•可通过使用取消标记来取消等待操作。

•创建实例之后可以递增它的信号计数。

•通过调用 Reset 方法,可在 Wait 返回之后重用实例。

•实例公开 WaitHandle 以便与其他 .NET Framework 同步 API(例如 WaitAll)进行集成。——MSDN

1.普通示例

usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceConsoleapplication18

{classPRogram

{staticCountdownEvent cde =null;/// <summary>/// 模拟建房子/// </summary>/// <param name="args"></param>staticvoidMain(string[] args)

{//建房子第一期工人string[] _bhPerson1 =newstring[5] {"Yan","Zhi","wei","Do","Work"};//建房子第二期工人string[] _bhPerson2 =newstring[3] {"Yan2","Zhi2","wei2"};//建房子第三期工人string[] _bhPerson3 =newstring[3] {"Yan3","Zhi3","wei3"};using(cde =newCountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工{cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人foreach(stringpersonin_bhPerson1)

{

Task.Factory.StartNew(() =>

{

BuilderHourseStep1(person);

});

}cde.Wait();//等待第一期建造完成Console.WriteLine("-----------------------");

cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人foreach(stringpersonin_bhPerson2)

{

Task.Factory.StartNew(() =>

{

BuilderHourseStep2(person);

});

}

cde.Wait();//等待第二期建造完成Console.WriteLine("-----------------------");

cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人foreach(stringpersonin_bhPerson3)

{

Task.Factory.StartNew(() =>

{

BuilderHourseStep3(person);

});

}

cde.Wait();//等待第三期建造完成Console.WriteLine("-----------------------");

}

}/// <summary>/// 建房子第一道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep1(stringperson)

{try{

Console.WriteLine(string.Format("『{0}』BuilderHourseStep1....", person));

}finally{cde.Signal();//建造完成一点后,通知监工}

}/// <summary>/// 建房子第二道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep2(stringperson)

{try{

Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));

}finally{

cde.Signal();

}

}/// <summary>/// 建房子第三道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep3(stringperson)

{try{

Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));

}finally{

cde.Signal();

}

}

}

}

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, "Courier New", courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp{ background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }代码效果

 

2.超时演示,延续上面例子,建造房子存在延期的情况,譬如某个工作工作懒散,那么需要给整个一期建造设置一个总的时限。

usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceConsoleApplication18

{classProgram

{staticCountdownEvent cde =null;staticintoverLimitTime = 5000;//第一期工作完成时间/// <summary>/// 模拟建房子/// </summary>/// <param name="args"></param>staticvoidMain(string[] args)

{try{//建房子第一期工人string[] _bhPerson1 =newstring[5] {"Yan","Zhi","wei","Do","Work"};//建房子第二期工人string[] _bhPerson2 =newstring[3] {"Yan2","Zhi2","wei2"};//建房子第三期工人string[] _bhPerson3 =newstring[3] {"Yan3","Zhi3","wei3"};using(cde =newCountdownEvent(Environment.ProcessorCount))//开始监管,相当于监工{

cde.Reset(_bhPerson1.Length);//设置第一期建造需要5个人Random _workTime =newRandom();foreach(stringpersonin_bhPerson1)

{

Task.Factory.StartNew(() =>

{int_doWorkTime = _workTime.Next(3000, 6000);//工人工作时间BuilderHourseStep1(person, _doWorkTime);

});

}bool_bdStep1Result = cde.Wait(overLimitTime);

Console.WriteLine(string.Format("第一期建造状态:{0}.", _bdStep1Result ==true?"完成":"延时"));//等待第一期建造完成 限制5秒内完成Console.WriteLine("-----------------------");if(!_bdStep1Result)return;

cde.Reset(_bhPerson2.Length);//设置第二期建需要三个人foreach(stringpersonin_bhPerson2)

{

Task.Factory.StartNew(() =>

{

BuilderHourseStep2(person);

});

}

cde.Wait();//等待第二期建造完成Console.WriteLine("-----------------------");

cde.Reset(_bhPerson3.Length);//设置第三期建需要三个人foreach(stringpersonin_bhPerson3)

{

Task.Factory.StartNew(() =>

{

BuilderHourseStep3(person);

});

}

cde.Wait();//等待第三期建造完成Console.WriteLine("-----------------------");

}

}catch(Exception ex)

{

Console.WriteLine(string.Format("Excepton Message: {0}", ex.Message.Trim()));

}finally{

Console.ReadLine();

}

}/// <summary>/// 建房子第一道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep1(stringperson,intdoWorkTime)

{bool_isDoWork = doWorkTime < overLimitTime;try{if(_isDoWork)

Console.WriteLine(string.Format("『{0}』做事情花费了,{1}s........", person, doWorkTime));elseConsole.WriteLine(string.Format("『{0}』做事情太墨迹,花费了{1}s....", person, doWorkTime));

Thread.Sleep(doWorkTime);

}finally{if(_isDoWork)

cde.Signal();//建造完成后,通知监工}}/// <summary>/// 建房子第二道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep2(stringperson)

{try{

Console.WriteLine(string.Format("『{0}』BuilderHourseStep2.....", person));

}finally{

cde.Signal();

}

}/// <summary>/// 建房子第三道所需要的工序/// </summary>/// <param name="person"></param>staticvoidBuilderHourseStep3(stringperson)

{try{

Console.WriteLine(string.Format("『{0}』BuilderHourseStep3.......", person));

}finally{

cde.Signal();

}

}

}

}

.csharpcode, .csharpcode pre

{

font-size: small;

color: black;

font-family: consolas, "Courier New", courier, monospace;

background-color: #ffffff;

/*white-space: pre;*/

}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt

{

background-color: #f4f4f4;

width: 100%;

margin: 0em;

}

.csharpcode .lnum { color: #606060; }代码效果

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航