ManualResetEvent和AutoResetEvent用法小試[C#]
功能一:ManualResetEvent用於等待所有線程結束再執行
功能二:AutoResetEvent用於線程間的同步
關於AutoResetEvent用法及ManualResetEvent和AutoResetEvent的區別,請參考另一篇博文[C# 多線程之同步輸出奇偶數]http://fengbo1983.blog.51cto.com/1391689/507094
------------------------------------------------------------------------------------------
老規矩,直接貼代碼,解釋寫得很清楚,就不一一說了.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
namespace ManualAndAutoResetEventTest
{
/// <summary>
/// 此類使用了ManualResetEvent,和AutoResetEvent
/// 功能一:ManualResetEvent用於,等待所有線程結束再執行
/// 功能二:AutoResetEvent用於線程間的同步
/// </summary>
class Program
{
#region === Filed ===
//定義兩個資源
static int nSubOne = 20;
static int nSubTwo = 15;
//設置手動重置信號量
ManualResetEvent manA ;
ManualResetEvent manB ;
//設置自動重置信號量
AutoResetEvent ateA = new AutoResetEvent(false);
AutoResetEvent ateB = new AutoResetEvent(false);
#endregion === Filed ===
#region === Main Method ===
static void Main(string[] args)
{
Program pg = new Program();
pg.ThreadTest();
}
#endregion === Main Method ===
#region === Private Method ===
void ThreadTest()
{
//初始化信號量
manA = new ManualResetEvent(false);
manB = new ManualResetEvent(false);
//啓動兩個線程
Thread thdOne = new Thread(new ThreadStart(ThreadOne));
thdOne.Start();
Thread thdTwo = new Thread(new ThreadStart(ThreadTwo));
thdTwo.Start();
//等信號量manA,manB都釋放了,才執行主線程
WaitHandle.WaitAll(new WaitHandle[2] { manA, manB });
int n = 0;
while (n < 10)
{
Console.WriteLine(n++);
Thread.Sleep(50);
}
Console.ReadKey ();
}
void ThreadOne()
{
while (nSubOne > 0)
{
ateA.WaitOne(); //ateA保持等待
Console.WriteLine("T___1___:" + nSubOne--);
ateB.Set(); //給ateB一個開始信號
Thread.Sleep(50); //可以看出,線程一和線程2的Sleep時間並不一樣,但是結果仍然是對的,
//這就是我們設置的同步信號量AutoResetEvent ateA,ateB的效果
}
manA.Set(); //給manA一個開始信號
}
void ThreadTwo()
{
ateA.Set(); //給ateA一個開始信號
//while (nSubTwo > 0) //可以在這試一下另一個線程操作,看是否主線程的確是等所有其它線程都執行完成才執行的.
//即看一下WaitHandle.WaitAll是否是真的有效了.
while (nSubOne > 0)
{
ateB.WaitOne(); //ateB保持等待
//Console.WriteLine("T___2___:" + nSubTwo--);
Console.WriteLine("T___2___:" + nSubOne--);
ateA.Set(); //給ateA一個開始信號
Thread.Sleep(500);
}
manB.Set(); //給manB一個開始信號
}
#endregion === Custom Method ===
}
}