您的位置:首页 > 编程语言 > C#

关于C#多线程处理

2016-01-05 20:24 453 查看
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()函数,则主线程会被阻塞
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C#多线程处理