关于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;
}
}
运行上面的代码,结果如下:
将上面的Pro()这个函数中的doevent.Set();这句注释掉,代码如下
public void Pro(object o=null)
{
Console.Write(“\t”+num+”\t”);
并且我们在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()函数,则主线程会被阻塞
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# 多线程+队列处理大批量数据,进而缩短处理时间
- c#中取整,向上取,向下取
- C# 的时间戳转换
- [c#]基类中不包含0个参数的构造函数
- C#中调用控制台程序时隐藏控制台窗口
- C#窗体中读取修改xml文件
- C# Best Practices - Define Proper Classes
- 正则表达式-Csharp
- C#程序运行过程中出错,报程序挂起,如“其他挂起签名1:xxx”
- C# 自定义事件
- C#托付和事件
- C# "资源管理器已停止工作"的编程解决方案
- C#集成ActiveX控件
- C#wmp.dll自动注册失败
- C# WinForm API 改进单实例运行
- 【C#——揭开你的面纱】
- C# 原样复制excel工作表
- C# 原样复制excel工作表
- c# 将秒数转换成时,分,秒的方法
- C#添加本地打印机