關於C#多線程處理

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace 控制檯程序
{
class MonitorSample
{
public class MyThread
{
private int num;
private ManualResetEvent doevent;
public MyThread(int num, ManualResetEvent doevent)
{
this.num = num;
this.doevent = doevent;
}

        public void Pro(object o=null)
        {
            Console.Write("\t"+num+"\t");

            Thread.Sleep(50000);
            doevent.Set();
        }
    }

    public static void Main(String[] args)
    {

        ManualResetEvent[] doevents = new ManualResetEvent[64];
        for (int i = 0; i < 64; i++)
        {
            doevents[i] = new ManualResetEvent(true);
        }
        for (int i = 0; i < 100; i++)
        {
            if (i < 64)
            {
                MyThread mythread = new MyThread(i, doevents[i]);
                ThreadPool.QueueUserWorkItem(new WaitCallback(mythread.Pro));
                Console.Write("正在分配");
            }
            else
            {
                Console.Write("已分配完");
                int index = WaitHandle.WaitAny(doevents);

                doevents[index].Reset();
                Console.Write("\t此時可用的:" + index+"\t");
                MyThread mythread=new MyThread(i,doevents[index]);
                ThreadPool.QueueUserWorkItem(new WaitCallback(mythread.Pro));
            }
        }
        Console.Write("ss");
            Console.Read();
    }
}

}

運行上面的代碼,結果如下:
這裏寫圖片描述
將上面的Pro()這個函數中的doevent.Set();這句註釋掉,代碼如下
public void Pro(object o=null)
{
Console.Write(“\t”+num+”\t”);

            Thread.Sleep(5000);
            //doevent.Set();
        }

並且我們在main函數中初始化ManualResetEvent數組時將每一個ManualResetEvent對象初始化爲false,代碼如下:
ManualResetEvent[] doevents = new ManualResetEvent[64];
for (int i = 0; i < 64; i++)
{
doevents[i] = new ManualResetEvent(false);
}
此時運行上面的代碼結果如下
這裏寫圖片描述
可以看到輸出到63就停止了
當初始化ManualResetEvent數組時將每一個ManualResetEvent對象初始化爲true時,修改代碼如下:
ManualResetEvent[] doevents = new ManualResetEvent[64];
for (int i = 0; i < 64; i++)
{
doevents[i] = new ManualResetEvent(true);
}
這裏寫圖片描述
結果跟第一次結果一樣,如果我們在初始化ManualResetEvent數組時將每一個ManualResetEvent對象初始化爲false時,但是在Pro()這個函數加上doevent.Set()這一句代碼,也就是上面註釋掉的代碼給加上,那麼運行結果會是怎樣的呢?
這裏寫圖片描述
實際上,跟上一步的結果一樣,到此可以看出我們在初始化ManualResetEvent時,如果我們將ManualResetEvent對象設置爲true,實際上和我們在每一個線程處理完後讓標記ManualResetEvent調用set()函數的效果是一樣的,也就是說當我們在初始化ManualResetEvent對象時,如果每個對象都設置爲true時,則不用在每一個線程處理完事情後都要調用set()函數,但如果我們在初始化ManualResetEvent對象的時候將每一個ManualResetEvent標記設置爲false時,爲了使後面的程序能夠繼續跑起來,我們就必須要在每一個線程處理完後調用set()函數,使標記ManualResetEvent處於終止狀態。那麼我們現在可以知道,如果ManualResetEvent標記處於終止狀態,則主線程不會因爲我們創建的線程而阻塞,但如果ManualResetEvent標記處於非終止狀態,即初始化爲false或者線程沒有調用set()函數,則主線程會被阻塞

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章