当前位置:编程学习 > C#/ASP.NET >>

步步为营C# 术漫谈六、线程控制(Thread)

概论

多线程在构建大型系统的时候是需要重点关注的一个重要方面,特别是在效率(系统跑得多快?)和性能(系统工作正常?)之间做一个权衡的时候。恰当的使用多线程可以极大的提高系统性能。

什么是线程?
每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。

 

在Win32环境中常用的一些模型。

·单线程模型

在这种线程模型中,一个进程中只能有一个线程,剩下的进程必须等待当前的线程执行完。这种模型的缺点在于系统完成一个很小的任务都必须占用很长的时间。

·块线程模型(单线程多块模型STA)

这种模型里,一个程序里可能会包含多个执行的线程。在这里,每个线程被分为进程里一个单独的块。每个进程可以含有多个块,可以共享多个块中的数据。程序规定了每个块中线程的执行时间。所有的请求通过Windows消息队列进行串行化,这样保证了每个时刻只能访问一个块,因而只有一个单独的进程可以在某一个时刻得到执行。这种模型比单线程模型的好处在于,可以响应同一时刻的多个用户请求的任务而不只是单个用户请求。但它的性能还不是很好,因为它使用了串行化的线程模型,任务是一个接一个得到执行的。(此模型相当于在多线程中在一个线程执行的过程中,另外的线程都处于挂起的状态,直到此线程执行结束,后再开始另一个线程)

·多线程块模型(自由线程块模型)

多线程块模型(MTA)在每个进程里只有一个块而不是多个块。这单个块控制着多个线程而不是单个线程。这里不需要消息队列,因为所有的线程都是相同的块的一个部分,并且可以共享。这样的程序比单线程模型和STA的执行速度都要块,因为降低了系统的负载,因而可以优化来减少系统idle的时间。这些应用程序一般比较复杂,因为程序员必须提供线程同步以保证线程不会并发的请求相同的资源,因而导致竞争情况的发生。这里有必要提供一个锁机制。但是这样也许会导致系统死锁的发生。

 

多线程在.NET里如何工作?

在本质上和结构来说,.NET是一个多线程的环境。有两种主要的多线程方法是.NET所提倡的:使用ThreadStart来开始你自己的进程,直接的(使用ThreadPool.QueueUserWorkItem)或者间接的(比如Stream.BeginRead,或者调用BeginInvoke)使用ThreadPool类。一般来说,你可以"手动"为长时间运行的任务创建一个新的线程,另外对于短时间运行的任务尤其是经常需要开始的那些,进程池是一个非常好的选择。进程池可以同时运行多个任务,还可以使用框架类。对于资源紧缺需要进行同步的情况来说,它可以限制某一时刻只允许一个线程访问资源。这种情况可以视为给线程实现了锁机制。线程的基类是System.Threading。所有线程通过CLI来进行管理。

 

如何使用线程

using System.Threading;
所有与多线程机制应用相关的类都是放在System.Threading命名空间中的.

Thread类用于创建线程.

ThreadPool类用于管理线程池等等.

如果你想在你的应用程序中使用多线程,就必须包含这个Thread类.


Thread类有几个至关重要的方法:

Start():启动线程.
Sleep(int):静态方法,暂停当前线程指定的毫秒数.
Abort():通常使用该方法来终止一个线程.
Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复.

Resume():恢复被Suspend()方法挂起的线程的执行.

 

简单线程示例

    class Program
    {
        static void Main(string[] args)
        {
            ThreadStart threadStart = new ThreadStart(SayHello);
            Thread thread = new Thread(threadStart);
            thread.Start();
            Thread.Sleep(5000);
        }

        public static void SayHello()
        {
            Console.Write("Spring Yang say hello to you. hello,every one.");
        }
    }

 

运行结果:

image

 

传递单个参数

    class Program
    {
        static void Main(string[] args)
        {
            string message = "Hello everyone.";
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SayHello);
            Thread thread = new Thread(threadStart);
            thread.Start(message);
            Thread.Sleep(5000);
        }

        public static void SayHello(object message)
        {
            Console.Write("Spring Yang say hello to you. {0}.",message);
        }
    }

 

结果:

image

 

 

传递多个参数:

 class Program
    {
        static void Main(string[] args)
        {
            ThreadTest threadTest = new ThreadTest("spring yang", "How are you?");
            ThreadStart threadStart = new ThreadStart(threadTest.SayHello);
            Thread thread = new Thread(threadStart);
            thread.Start();
            Thread.Sleep(5000);
        }


    }

    public class ThreadTest
    {
        private string _userName;
        private string _message;

        public string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }

        public string Message
        {
            get { return _message; }
            set { _message = value; }<

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,