C# 多线程编程

一、Thread 基础

     进程:  当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。
     线程:  线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数(方法)。
     多线程: 多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
   


二、 多线程
     优点:可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。
     缺点:线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
           多线程需要协调和管理,所以需要CPU时间跟踪线程;
           线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
           线程太多会导致控制太复杂,最终可能造成很多Bug;

 

 

三、控制线程的类和方法
     类:using System.Threading; Thread类
     Thread类的方法:Start():   启动线程;
                     Sleep(int):静态方法,暂停当前线程指定的毫秒数;
                     Abort():    通常使用该方法来终止一个线程;
                     Suspend(): 该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;
                     Resume():  恢复被Suspend()方法挂起的线程的执行。
                     Priority    枚举设置线程的优先级,由高到低 Highest,AboveNormal,Normal,BelowNormal,Lowest;系统默认为ThreadPriority.Normal 

 

 

 

  在实例化Thread的实例,需要提供一个委托,在实例化这个委托时所用到的参数是线程将来启动的方法。在.NET中提供了两种启动线程的方式,一种是不带参数的启动方式,另一种是带参数的启动方式。

  1. 不带参数的启动方式

     在大型缓存的时候我们会经常会用线程,当前程序去缓存中提取数据,开启另一个线程判断当前的缓存数据是否过期,是否需要从数据库提取最新数据。

     定义性别的枚举

    /// <summary>
    
///  姓名枚举
    
/// </summary>
    enum PersonSexTypeEnum
    {

        Man,
        Woman,
    }

 

   定义Person 类,成员

  internal class Person
    {

        
/// <summary>
        
/// 姓名
        
/// </summary>
        public string Name { getset; }

        
/// <summary>
        
/// 年龄
        
/// </summary>
        public int Age { getset; }

        
/// <summary>
        
/// 生日月份
        
/// </summary>
        public int BirthMonth { getset; }



        
/// <summary>
        
/// 性别
        
/// </summary>
        public PersonSexTypeEnum sex;


        
/// <summary>
        
/// 人
        
/// </summary>
        public Person person { getset; }
    }

 

    

       Thread

    public class MyThread
    {
        
static void Main(string[] args)
        {

            Person p 
= new Person();
            p.Name 
= "张三";
            p.Age 
= 22;
            p.BirthMonth 
= 12;
            p.sex 
= PersonSexTypeEnum.Man;
            System.Threading.Thread thrad 
= new System.Threading.Thread(new System.Threading.ThreadStart(p.PersonToString));
            thrad.Start();

        }
    }

     上面我们实例化 person 类, 使用线程thrad 调用 p.personToString 方法,这个方法在执行完毕后,线程结束, 不要理解为是调用了 thrad. Abort()    abort 是停止线程,你看到这里肯定会问,你实例化了Person 给Person 成员都赋值,在线程的方法中不就可以使用了吗? 刚学习C# 的人可能都知道了 。 

        /// <summary>
        
/// 不带参数
        
/// </summary>
        public void PersonToString()
        {
            System.Threading.Thread.Sleep(
60);
            Console.WriteLine(
"no parameter ");
        }

 

   2.这里我们介绍带参数的启动方法

      如果要在实例化线程时要带一些参数,就不能用ThreadStart委托作为构造函数的参数来实例化Thread了,而要parameterizedThreadStart委托,和ThreadStart 一样的是也是线程启动时要执行的方法,和ThreadStart不同的是,他在实例化时可以用一个带有object参数的方法作为构造函数的参数,而实例化ThreadStart时所用到得方法是没有参数的。

       

 

 

代码
     static void Main(string[] args)
        {


            Person p 
= new Person();
            p.Name 
= "张三";
            p.Age 
= 22;
            p.BirthMonth 
= 12;
            p.sex 
= PersonSexTypeEnum.Man;
            
//带参数的线程
            System.Threading.Thread thradparameter = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(p.PersonToString));
            thradparameter.Start(p);

        }

 

 

带参数的方法  

 

 

代码
   /// <summary>
        
///  传递一个Object
        
/// </summary>
        
/// <param name="obj"></param>
        public void PersonToString(object obj)
        {
            
if (obj == null)
                
return;
            
if (obj is Person)
            {
                Person p 
= obj as Person;
                System.Threading.Thread.Sleep(
61);
                Console.WriteLine(
"person name  " + p.Name + "Age" + p.Age);

            }
        }
posted @ 2010-05-10 10:24  dearpine  阅读(949)  评论(0编辑  收藏  举报