文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>浅谈C#中的多线程编程[1]

浅谈C#中的多线程编程[1]

时间:2011-03-09  来源:Ellic

  记录,做到温故而知新。

    一、相关概念:
  什么是进程?

  当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。而一个进程又是由多个线程所组成的。

  什么是线程?

  线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。

  什么是多线程?

  多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

  多线程的好处:

  可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。

  多线程编程有好处,也有不好的地方,如:

线程也是对象,需要占用内存,线程越多占用内存越多;

多线程需要协调和管理,所以需要CPU时间跟踪线程;

线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;

线程太多会导致控制太复杂,最终可能带来产生Bug的风险。

 

  二、Thread类

先来理解下Thread类,这是实现多线程编程的基础。Thread类位于System.Threading命名空间,其构造函数为:

public Thread(ParameterrizedThreadStart start)

public Thread(ThreadStart start)

public Thread(ParameterizedThreadStart start, int maxStackSize)

public Thread(ThreadStart start, int maxStackSize)

这些构造函数涉及3种类型的参数:

1)ParameterizedThreadStart:是一个委托类型,表示此线程开始执行时要调用的方法,支持向调用的方法传递一个参数。

2)ThreadStart:是一个委托类型,表示此线程开始执行时要调用的方法没有参数的委托类型,不支持向调用的方法传递一个参数。

3)maxStackSize:表示线程要使用的最大堆栈大小,如果为0刚使用可执行文件的文件头中指定的默认最大堆栈大小。

Thread类有几个至关重要的方法,描述如下:

Start():启动线程;

Sleep(int):静态方法,暂停当前线程指定的毫秒数;

Abort():通常使用该方法来终止一个线程;

Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;

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

 

  Thread类基本的使用代码如下:
  

View Code using System;
using System.Threading;
namespace ProgrammingCSharp4
{
    public class Program
    {
        public static void Main(string[] args)
        {            
            Console.WriteLine("[主线程id:{0}]",Thread.CurrentThread.ManagedThreadId);
            Thread thread1 = new Thread(Print);
            thread1.Start();
            Thread thread2 = new Thread(PrintEx);
            thread2.Start("测试");
            Console.ReadKey(true);
        }
        public static void Print()
        {
            int threadId = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("[当前线程id:{0}]{1}",threadId,DateTime.Now.ToShortTimeString());
        }
        public static void PrintEx(object obj)
        {
            int threadId = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("[当前线程id:{0}]{1}",threadId,obj);
        }
    }
}

 

  三、线程池的使用

C#中,我们可以通过一种叫做“池(Pool)”的技术来优化对象的使用,其原理是预先创建一定数量的对象放在“池”里,在对象被请求的时候,某个对象被从“池”中取出供使用,使用完毕再重新放回“池”中,等待下一次的请求。我们可以自己实现这样的线程池,也可以使用.NET Framework为我们所提供的线程池,它叫做TreadPool,位于System.Threading命名空间。

需要注意的是线程池中的线程均为后台线程,即它们的IsBackground属性为True。也就是说在所有的前台线程都已经退出后,ThreadPool中的线程不会让应用程序继续保持运行。

所以当我们执行一些简单的、耗时短暂的任务时,才应该使用到线程池,在下面的情况下则不应该使用线程池技术:

Ø 当需要创建一个前台线程时;

Ø 线程池中的线程都是默认优先级的,因此当需要创建具有特定优先级的线程时就不应该使用线程池;

Ø 当需要某个任务只和特定的线程关联时,因为无法选择执行任务时使用的是哪一个具体的线程;

Ø 当需要中止特定的线程时不应使用线程池,它不提供这个功能;

Ø 线程执行时间比较长时;

 

要使用ThreadPool中的线程,需要使用TheadPool.QueueUserWorkItem这个静态方法指定线程要调用的方法,该方法有两个重载版本:

public static bool QueueUserWorkItem(WaitCallBack callBack)

public static bool QueueUserWorkItem(WaitCallBack callBack,object state)

WaitCallBack是一个委托类型,下面是线程池使用的例子:
  

View Code using System;
using System.Threading;
namespace AsynchronousSample
{
    class Program
    {
        public static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(Counter);
            ThreadPool.QueueUserWorkItem(Counter,"AsynchronousSample Test");
            Console.WriteLine("[Thread ID = {0}]The main thread is started.",Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(500);
            Console.WriteLine("The main thread is closed."); 
            
            Console.ReadKey(true);
        }
        
        private static void Counter(object state)
        {
            Console.WriteLine("Counting begins, from 1 to 100:");
            Console.WriteLine("the Parameter is:{0}",state);
            for(int counter = 0 ; counter <100;counter++)
            {
                if(null==state)
                {
                    Console.WriteLine("[Thread ID = {0}] {1}",Thread.CurrentThread.ManagedThreadId,counter);
                }else
                {
                    Console.WriteLine("[Thread ID = {0}] {1}",Thread.CurrentThread.ManagedThreadId,state);
                }
                Thread.Sleep(100);
            }
        }
    }
}


  未完待续,下次接着复习Thread的相关属性与用法。

 

相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载