zoukankan      html  css  js  c++  java
  • C#多线程学习(二) 如何操纵一个线程

    下面我们就动手来创建一个线程,使用Thread类创建线程时,只需提供线程入口即可。(线程入口使程序知道该让这个线程干什么事)

    在C#中,线程入口是通过ThreadStart代理(delegate)来提供的,你可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,当调用Thread.Start()方法后,线程就开始执行ThreadStart所代表或者说指向的函数。

    打开你的VS.net,新建一个控制台应用程序(Console Application),编写完全控制一个线程的代码示例:

    //ThreadTest.cs 

    using System;
    using System.Threading; 

    namespace ThreadTest
    {
      
    public class Alpha
      {
          
    public void Beta()
          {
            
    while (true)
            {
              Console.WriteLine(
    "Alpha.Beta is running in its own thread.");
            }
          }
      }; 

      
    public class Simple
      {
          
    public static int Main()
          {
            Console.WriteLine(
    "Thread Start/Stop/Join Sample");

                    Alpha oAlpha 
    = new Alpha();
            file:
    //这里创建一个线程,使之执行Alpha类的Beta()方法
            Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
            oThread.Start();
            
    while (!oThread.IsAlive)
                   Thread.Sleep(
    1);
            oThread.Abort();
            oThread.Join();
            Console.WriteLine();
            Console.WriteLine(
    "Alpha.Beta has finished"); 
            
    try 
            {
              Console.WriteLine(
    "Try to restart the Alpha.Beta thread");
              oThread.Start();
            }
            
    catch (ThreadStateException) 
            {
              Console.Write(
    "ThreadStateException trying to restart Alpha.Beta. ");
              Console.WriteLine(
    "Expected since aborted threads cannot be restarted.");
              Console.ReadLine();
            }
            
    return 0;
          }
      }
    }

    这段程序包含两个类Alpha和Simple,在创建线程oThread时我们用指向Alpha.Beta()方法的初始化了ThreadStart代理(delegate)对象,当我们创建的线程oThread调用oThread.Start()方法启动时,实际上程序运行的是Alpha.Beta()方法:

    Alpha oAlpha = new Alpha();
      Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
      oThread.Start(); 
     
    然后在Main()函数的while循环中,我们使用静态方法Thread.Sleep()让主线程停了1ms,这段时间CPU转向执行线程oThread。然后我们试图用Thread.Abort()方法终止线程oThread,注意后面的oThread.Join(),Thread.Join()方法使主线程等待,直到oThread线程结束。你可以给Thread.Join()方法指定一个int型的参数作为等待的最长时间。之后,我们试图用Thread.Start()方法重新启动线程oThread,但是显然Abort()方法带来的后果是不可恢复的终止线程,所以最后程序会抛出ThreadStateException异常。

    主线程Main()函数

    所有线程都是依附于Main()函数所在的线程的,Main()函数是C#程序的入口,起始线程可以称之为主线程。
    如果所有的前台线程都停止了,那么主线程可以终止,而所有的后台线程都将无条件终止。
    所有的线程虽然在微观上是串行执行的,但是在宏观上你完全可以认为它们在并行执行。

    Thread.ThreadState 属性

    这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。
    ThreadState 属性的取值如下:
    Aborted:线程已停止;
    AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;
    Background:线程在后台执行,与属性Thread.IsBackground有关;
    Running:线程正在正常运行;
    Stopped:线程已经被停止;
    StopRequested:线程正在被要求停止;
    Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);
    SuspendRequested:线程正在要求被挂起,但是未来得及响应;
    Unstarted:未调用Thread.Start()开始线程的运行;
    WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;

    上面提到了Background状态表示该线程在后台运行,那么后台运行的线程有什么特别的地方呢?其实后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序的终止。一旦一个进程所有的前台线程都终止后,CLR(通用语言运行环境)将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。

    线程的优先级

    当线程之间争夺CPU时间时,CPU 是按照线程的优先级给予服务的。在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

    给一个线程指定优先级,我们可以使用如下代码:
    //设定优先级为最低
    myThread.Priority=ThreadPriority.Lowest;

    通过设定线程的优先级,我们可以安排一些相对重要的线程优先执行,例如对用户的响应等等。

  • 相关阅读:
    Knockout应用开发指南 第八章:简单应用举例(2)
    微软ASP.NET站点部署指南(7):生产环境部署
    Knockout应用开发指南 第七章:Mapping插件
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(6)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(5)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(3)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(9)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(8)
    Microsoft Visual Studio .NET 2003 引导程序插件下载地址(非官方)
    Vs2010在没有安装SQL Server 2005/2008 Express时如何连接MDF数据文件?
  • 原文地址:https://www.cnblogs.com/xugang/p/1138841.html
Copyright © 2011-2022 走看看