轉 http://www.cnblogs.com/li-peng/p/3291306.htmlhtml
今天詳細說一下ManualResetEvent函數
它能夠通知一個或多個正在等待的線程已發生事件,容許線程經過發信號互相通訊,來控制線程是否可心訪問資源ui
當一個線程開始一個活動(此活動必須完成後,其餘線程才能開始)時,它調用 Reset 以將 ManualResetEvent 置於非終止狀態。此線程可被視爲控制 ManualResetEvent。調用 ManualResetEvent上的 WaitOne 的線程將阻止,並等待信號。當控制線程完成活動時,它調用 Set 以發出等待線程能夠繼續進行的信號。並釋放全部等待線程。spa
一旦它被終止,ManualResetEvent 將保持終止狀態,直到它被手動重置。即對 WaitOne 的調用將當即返回。線程
上面是它的功能描述,你可能會有點暈。我會用代碼一點一點解釋它,看完我寫的這些內容,你本身運行一下代碼你就會明白它的功能3d
源代碼:ManualResetEventDemo.rarcode
咱們從初始化來開始講htm
能夠經過將布爾值傳遞給構造函數來控制 ManualResetEvent 的初始狀態,若是初始狀態處於終止狀態,爲 true;不然爲 false。blog
我用代碼 讓你們看一下什麼是終止狀態和非終止狀態事件
先看一下代碼
class
Program
{
static
ManualResetEvent _mre =
new
ManualResetEvent(
false
);
static
void
Main(
string
[] args)
{
Thread[] _threads =
new
Thread[3];
for
(
int
i = 0; i < _threads.Count(); i++)
{
_threads[i] =
new
Thread(ThreadRun);
_threads[i].Start();
}
}
static
void
ThreadRun()
{
int
_threadID = 0;
while
(
true
)
{
_mre.WaitOne();
_threadID = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine(
"current Tread is "
+ _threadID);
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
|
當初始化爲true時,爲終止狀態
static
ManualResetEvent _mre =
new
ManualResetEvent(
true
);
|
執行結果
當初始化爲false時,爲非終止狀態
static
ManualResetEvent _mre =
new
ManualResetEvent(
false
);
|
執行結果爲
這樣咱們就能看出來
終止狀態時WaitOne()容許線程訪問下邊的語句
非終止狀態時WaitOne()阻塞線程,不容許線程訪問下邊的語句
咱們也能夠把WaitOne()放在方法最下邊
static
void
ThreadRun()
{
int
_threadID = 0;
while
(
true
)
{
_threadID = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine(
"current Tread is "
+ _threadID);
Thread.Sleep(TimeSpan.FromSeconds(2));
_mre.WaitOne();
}
}
|
當初始化爲true時執行結果和上邊的同樣會不停的執行
初始化爲false時執行到waitOne()時就阻塞線程不會再往下執行了
接下來你可能就會想當在非終止狀態時怎麼讓線程繼續執行,怎麼再讓它停下來,這就要用了set()和Reset()方法了
把非終止狀態改成終止狀態用Set()方法
把終止狀態改成非終止狀態用Reset()方法
我用用代碼來實現它們只要把咱們上 邊的代碼作一下改動
class
Program
{
static
ManualResetEvent _mre =
new
ManualResetEvent(
false
);
static
void
Main(
string
[] args)
{
Console.WriteLine(
"輸入1爲Set() 開始運行"
);
Console.WriteLine(
"輸入2爲Reset() 暫停運行"
);
Thread[] _threads =
new
Thread[3];
for
(
int
i = 0; i < _threads.Count(); i++)
{
_threads[i] =
new
Thread(ThreadRun);
_threads[i].Start();
}
while
(
true
)
{
switch
(Console.ReadLine())
{
case
"1"
:
_mre.Set();
Console.WriteLine(
"開始運行"
);
break
;
case
"2"
:
_mre.Reset();
Console.WriteLine(
"暫停運行"
);
break
;
default
:
break
;
}
}
}
static
void
ThreadRun()
{
int
_threadID = 0;
while
(
true
)
{
_threadID = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine(
"current Tread is "
+ _threadID);
Thread.Sleep(TimeSpan.FromSeconds(2));
_mre.WaitOne();
}
}
}
|
當輸入1 時會調用 Set()方法 ManualResetEvent 處於終止狀態會WaitOne不會阻塞線程會一直運行下去
當輸入2時會調用 Reser()方法ManualResetEvent處於非終止狀態WaitOne會阻塞線程直到再調用 Set()方法
看一下執行結果吧