[C#] ManualResetEvent 與 AutoResetEvent應用

當我們想將一段代碼暫停在某行時,可以用ManualResetEvent與AutoResetEvent的方式,例如在一段While迴圈中

可利用ManualReset hold住迴圈使之暫停,而ManualResetEvent與AutoResetEvent的差別將近文中進行介紹。

當我們想將一段代碼暫停在某行時,可以用ManualResetEvent與AutoResetEvent的方式,例如在一段While迴圈中

可利用ManualReset hold住迴圈使之暫停。

而AutoResetEvent差別在於,當主動給過一次Set後,下次再執行到此行代碼時會自動Reset,使之hold住。

首先簡單拉一個簡單的Form如圖所示,兩個Button分別為Set與 Reset功能用,另外兩個TextBox則是觀察用

public partial class Form1 : Form
    {
        ManualResetEvent mMRE = new ManualResetEvent(true);
        AutoResetEvent mARE = new AutoResetEvent(false);
        Thread testThread;
        public Form1()
        {
            InitializeComponent();
            Form1.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            testThread = new Thread(_testThread);
            testThread.Start();
        }

        private void _testThread()
        {
            int i1=0, i2=0;
            while (true)
            {
                textBox1.Text = "" + i1;
                mMRE.WaitOne(Timeout.Infinite);
                textBox2.Text = "" + i2;
                i1++;
                i2++;
            }
        }

        private void Setbtn_Click(object sender, EventArgs e)
        {
            mMRE.Set();
        }

        private void resetbtn_Click(object sender, EventArgs e)
        {
            mMRE.Reset();
        }
    }

完整代碼如上,建立一個testThread並使用while迴圈使之不斷在Textbox上打印出i1與i2,並建立了

        ManualResetEvent mMRE = new ManualResetEvent(true);
        AutoResetEvent mARE = new AutoResetEvent(false);

兩個Event的初始化都有true或false可設定, 設置true的話,當執行到mMRE.WaitOne(Timeout.Infinite)時,將不會Hold住,反之則是會Hold住,而AutoResetEvent初始設置為true時,

第一次執行mARE.WaitOne(Timeout.Infinite)時不會Hold住,但下次將自動設為Reset狀態使之Hold住。

其中WaitOne(Timeout.Infinite)代表的是當mMRE.Reset時,此行代碼無限期hold住,如果設為WaitOne(1000),則是執行到此行代碼暫停1秒。

另外也可以使用下面代碼的方式使while迴圈break

if(mMRE.WaitOut(0))break;

預設為false時,while迴圈內並不會執行此行代碼,使用Button使mMRE.Set()時,觸發WaitOne使之break