C#高级编程--进程与线程

       进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。

       线程(Thread)是进程中的基本执行单元,是操作系统分配CPU时间的基本单位,一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。

       

创建线程的一种简单方式是定义一个委托,并异步调用它。委托是方法的类型安全的引用。Delegate类 还支持异步地调用方法。在后台,Delegate类会创建一个执行任务的线程。

接下来定义一个方法,使用委托异步调用(开启一个线程去执行这个方法)
static int TakesAWhile(int data,int ms){
		Console.WriteLine("TakesAWhile started!");
		Thread.Sleep(ms);//程序运行到这里的时候会暂停ms毫秒,然后继续运行下一语句
		Console.WriteLine("TakesAWhile completed");
		return ++data;
	}
	public delegate int TakesAWhileDelegate(int data,int ms);// 声明委托
	static void Main(){
		TakesAWhileDelegate d1 = TakesAWhile;
		IAsyncResult ar = d1.BeginInvoke(1,3000,null,null);
		while(ar.IsCompleted ==false ){
			Console.Write(".");
			Thread.Sleep(50);
		}
		int result = d1.EndInvoke(ar);
		Console.WriteLine("Res:"+result);
	}
	代码来自siki老师


当我们通过BeginInvoke开启一个异步委托的时候,返回的结果是IAsyncResult,我们可以通过它的AsyncWaitHandle属性访问等待句柄。这个属性返回一个WaitHandler类型的对象,它中的WaitOne()方法可以等待委托线程完成其任务,WaitOne方法可以设置一个超时时间作为参数(要等待的最长时间),如果发生超时就返回false。

static void Main(){

  TakesAWhileDelegated1 = TakesAWhile;

  IAsyncResultar = d1.BeginInvoke(1,3000,null,null);

  while(true){

  Console.Write(".");

  if(ar.AsyncWaitHanle.WaitOne(50,false)){

  Console.WriteLine("Canget result now");

  break;

  }

 

  }

  intresult = d1.EndInvoke(ar);

  Console.WriteLine("Res:"+result);

}//代码来自SIKI老师

等待委托的结果的第3种方式是使用异步回调。在BeginInvoke的第三个参数中,可以传递一个满足AsyncCallback委托的方法,AsyncCallback委托定义了一个IAsyncResult类型的参数其返回类型是void。对于最后一个参数,可以传递任意对象,以便从回调方法中访问它。(我们可以设置为委托实例,这样就可以在回调方法中获取委托方法的结果)


static void Main(){
	TakesAWhileDelegate d1 = TakesAWhile;
	d1.BeginInvoke(1,3000,TakesAWhileCompleted,d1);
	while(true){
		Console.Write(".");
		Thread.Sleep(50);
	}
}
static void TakesAWhileCompleted(IAsyncResult ar){//回调方法是从委托线程中调用的,并不是从主线程调用的,可以认为是委托线程最后要执行的程序
	if(ar==null) throw new ArgumentNullException("ar");
	TakesAWhileDelegate d1 = ar.AsyncState as TakesAWhileDelegate;
	int result = d1.EndInvoke(ar);
	Console.Write("Res:"+result);
}

使用Thread类可以创建和控制线程。Thread构造函数的参数是一个无参无返回值的委托类型。

static void Main(){

  vart1 = new Thread(ThreadMain);

  t1.Start();

  Console.WriteLine("Thisis the main thread.");

}

static void ThreadMain(){

  Console.WriteLine("Runningin a thread.");

}

在这里哪个先输出是无法保证了线程的执行有操作系统决定,只能知道Main线程和分支线程是同步执行的。在这里给Thread传递一个方法,调用Thread的Start方法,就会开启一个线程去执行,传递的方法。

创建线程需要时间。 如果有不同的小任务要完成,就可以事先创建许多线程 ,在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。

不需要 自己创建线程池,系统已经有一个ThreadPool类管理线程。这个类会在需要时增减池中线程的线程数,直到达到最大的线程数。 池中的最大线程数是可配置的。 在双核 CPU中 ,默认设置为1023个工作线程和 1000个I/o线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池中可用的最大线程数。如果有更多的作业要处理,线程池中线程的个数也到了极限,最新的作业就要排队,且必须等待线程完成其任务。

static void Main(){
	int nWorkerThreads;
	int nCompletionPortThreads;
	ThreadPool.GetMaxThreads(out nWorkerThreads,out nCompletionPortThreads);
	Console.WriteLine("Max worker threads : " +nWorkerThreads+" I/O completion threads :"+nCompletionPortThreads );
	for(int i=0;i<5;i++){
		ThreadPool.QueueUserWorkItem(JobForAThread);
	}
	Thread.Sleep(3000);
}
static void JobForAThread(object state){
	for(int i=0;i<3;i++){
		Console.WriteLine("Loop "+i+" ,running in pooled thread "+Thread.CurrentThread.ManagedThreadId);
		Thread.Sleep(50);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值