作為等同于Java的wait,notify,notifyAll的存在,AutoResetEvent和ManualResetEvent分別實現了notify和notifyAll的功能,下面的代碼簡單講解了一下實現原理,并展示了這一過程。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadTest
{
class Program
{
//新建一個默認無信號的手動重置線程事件
private void Test()
{
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
//線程傳參需要通過ParameterizedThreadStart委托,并在Start時附加參數。
new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread1", manualResetEvent));
new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread2", manualResetEvent));
new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread3", autoResetEvent));
new Thread(new ParameterizedThreadStart(MyThreadHandler)).Start(new ParamStruct("Thread4", autoResetEvent));
Thread.Sleep(1000);
//manualResetEvent在Set方法中,會讓信號狀態從無到有,從而讓所有wait狀態的線程喚醒,實現NotifyAll
manualResetEvent.Set();
//autoResetEvent在Set方法中,會在第一個處于wait狀態的線程喚醒后將信號狀態Reset,變為無信號,實現NotifyOne
autoResetEvent.Set();
Thread.Sleep(1000);
autoResetEvent.Set();
Console.ReadKey();
}
static void Main(string[] args)
{
new Program().Test();
}
private void MyThreadHandler(object obj)
{
if (obj is ParamStruct paramStruct)
{
Console.WriteLine(paramStruct.threadName);
paramStruct.resetEvent.WaitOne();
Console.WriteLine(paramStruct.threadName + " finished on " + DateTime.Now);
}
}
}
class ParamStruct
{
public string threadName;
public EventWaitHandle resetEvent;
public ParamStruct(string threadName, EventWaitHandle resetEvent)
{
this.threadName = threadName;
this.resetEvent = resetEvent;
}
}
}