Csharp/C#教程:C# 多线程分享

C#多线程

线程被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了CPU周期的浪费,同时提高了应用程序的效率。

到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。

线程生命周期

线程生命周期开始于System.Threading.Thread类的对象被创建时,结束于线程被终止或完成执行时。

下面列出了线程生命周期中的各种状态:

未启动状态:当线程实例被创建但Start方法未被调用时的状况。 就绪状态:当线程准备好运行并等待CPU周期时的状况。 不可运行状态:下面的几种情况下线程是不可运行的:

已经调用Sleep方法 已经调用Wait方法 通过I/O操作阻塞 死亡状态:当线程已完成执行或已中止时的状况。 主线程

在C#中,System.Threading.Thread类用于线程的工作。它允许创建并访问多线程应用程序中的单个线程。进程中第一个被执行的线程称为主线程

当C#程序开始执行时,主线程自动创建。使用Thread类创建的线程被主线程的子线程调用。您可以使用Thread类的CurrentThread属性访问线程。

下面的程序演示了主线程的执行:

实例 usingSystem;
usingSystem.Threading;
namespaceMultithreadingApplication
{
  classMainThreadProgram
  {
    staticvoidMain(string[]args)
    {
      Threadth=Thread.CurrentThread;
      th.Name="MainThread";
      Console.WriteLine("Thisis{0}",th.Name);
      Console.ReadKey();
    }
  }
}

当上面的代码被编译和执行时,它会产生下列结果:

ThisisMainThread Thread类常用的属性和方法

下表列出了Thread类的一些常用的属性

属性描述 CurrentContext获取线程正在其中执行的当前上下文。 CurrentCulture获取或设置当前线程的区域性。 CurrentPrincipal获取或设置线程的当前负责人(对基于角色的安全性而言)。 CurrentThread获取当前正在运行的线程。 CurrentUICulture获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源。 ExecutionContext获取一个ExecutionContext对象,该对象包含有关当前线程的各种上下文的信息。 IsAlive获取一个值,该值指示当前线程的执行状态。 IsBackground获取或设置一个值,该值指示某个线程是否为后台线程。 IsThreadPoolThread获取一个值,该值指示线程是否属于托管线程池。 ManagedThreadId获取当前托管线程的唯一标识符。 Name获取或设置线程的名称。 Priority获取或设置一个值,该值指示线程的调度优先级。 ThreadState获取一个值,该值包含当前线程的状态。

下表列出了Thread类的一些常用的方法

序号方法名&描述 1publicvoidAbort()
在调用此方法的线程上引发ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。 2publicstaticLocalDataStoreSlotAllocateDataSlot()
在所有的线程上分配未命名的数据槽。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 3publicstaticLocalDataStoreSlotAllocateNamedDataSlot( stringname)
在所有线程上分配已命名的数据槽。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 4publicstaticvoidBeginCriticalRegion()
通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常的影响可能会危害应用程序域中的其他任务。 5publicstaticvoidBeginThreadAffinity()
通知主机托管代码将要执行依赖于当前物理操作系统线程的标识的指令。 6publicstaticvoidEndCriticalRegion()
通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常仅影响当前任务。 7publicstaticvoidEndThreadAffinity()
通知主机托管代码已执行完依赖于当前物理操作系统线程的标识的指令。 8publicstaticvoidFreeNamedDataSlot(stringname)
为进程中的所有线程消除名称与槽之间的关联。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 9publicstaticObjectGetData( LocalDataStoreSlotslot )
在当前线程的当前域中从当前线程上指定的槽中检索值。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 10publicstaticAppDomainGetDomain()
返回当前线程正在其中运行的当前域。 11publicstaticAppDomainGetDomainID()
返回唯一的应用程序域标识符。 12publicstaticLocalDataStoreSlotGetNamedDataSlot( stringname )
查找已命名的数据槽。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 13publicvoidInterrupt()
中断处于WaitSleepJoin线程状态的线程。 14publicvoidJoin()
在继续执行标准的COM和SendMessage消息泵处理期间,阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式。 15publicstaticvoidMemoryBarrier()
按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行MemoryBarrier调用之后的内存存取,再执行MemoryBarrier调用之前的内存存取的方式。 16publicstaticvoidResetAbort()
取消为当前线程请求的Abort。 17publicstaticvoidSetData( LocalDataStoreSlotslot, Objectdata )
在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。 18publicvoidStart()
开始一个线程。 19publicstaticvoidSleep( intmillisecondsTimeout )
让线程暂停一段时间。 20publicstaticvoidSpinWait( intiterations )
导致线程等待由iterations参数定义的时间量。 21publicstaticbyteVolatileRead( refbyteaddress )
publicstaticdoubleVolatileRead( refdoubleaddress )
publicstaticintVolatileRead( refintaddress )
publicstaticObjectVolatileRead( refObjectaddress )

读取字段值。无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。此方法有不同的重载形式。这里只给出了一些形式。 22publicstaticvoidVolatileWrite( refbyteaddress, bytevalue )
publicstaticvoidVolatileWrite( refdoubleaddress, doublevalue )
publicstaticvoidVolatileWrite( refintaddress, intvalue )
publicstaticvoidVolatileWrite( refObjectaddress, Objectvalue )

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。此方法有不同的重载形式。这里只给出了一些形式。 23publicstaticboolYield()
导致调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程。
创建线程

线程是通过扩展Thread类创建的。扩展的Thread类调用Start()方法来开始子线程的执行。

下面的程序演示了这个概念:

实例 usingSystem;
usingSystem.Threading;
namespaceMultithreadingApplication
{
  classThreadCreationProgram
  {
    publicstaticvoidCallToChildThread()
    {
      Console.WriteLine("Childthreadstarts");
    }
    
    staticvoidMain(string[]args)
    {
      ThreadStartchildref=newThreadStart(CallToChildThread);
      Console.WriteLine("InMain:CreatingtheChildthread");
      ThreadchildThread=newThread(childref);
      childThread.Start();
      Console.ReadKey();
    }
  }
}

当上面的代码被编译和执行时,它会产生下列结果:

InMain:CreatingtheChildthread Childthreadstarts 管理线程

Thread类提供了各种管理线程的方法。

下面的实例演示了sleep()方法的使用,用于在一个特定的时间暂停线程。

实例 usingSystem;
usingSystem.Threading;
namespaceMultithreadingApplication
{
  classThreadCreationProgram
  {
    publicstaticvoidCallToChildThread()
    {
      Console.WriteLine("Childthreadstarts");
      //线程暂停5000毫秒
      intsleepfor=5000;
      Console.WriteLine("ChildThreadPausedfor{0}seconds",
               sleepfor/1000);
      Thread.Sleep(sleepfor);
      Console.WriteLine("Childthreadresumes");
    }
    
    staticvoidMain(string[]args)
    {
      ThreadStartchildref=newThreadStart(CallToChildThread);
      Console.WriteLine("InMain:CreatingtheChildthread");
      ThreadchildThread=newThread(childref);
      childThread.Start();
      Console.ReadKey();
    }
  }
}

当上面的代码被编译和执行时,它会产生下列结果:

InMain:CreatingtheChildthread Childthreadstarts ChildThreadPausedfor5seconds Childthreadresumes 销毁线程

Abort()方法用于销毁线程。

通过抛出threadabortexception在运行时中止线程。这个异常不能被捕获,如果有finally块,控制会被送至finally块。

下面的程序说明了这点:

实例 usingSystem;
usingSystem.Threading;
namespaceMultithreadingApplication
{
  classThreadCreationProgram
  {
    publicstaticvoidCallToChildThread()
    {
      try
      {
        Console.WriteLine("Childthreadstarts");
        //计数到10
        for(intcounter=0;counter<=10;counter++)
        {
          Thread.Sleep(500);
          Console.WriteLine(counter);
        }
        Console.WriteLine("ChildThreadCompleted");
      }
      catch(ThreadAbortExceptione)
      {
        Console.WriteLine("ThreadAbortException");
      }
      finally
      {
        Console.WriteLine("Couldn'tcatchtheThreadException");
      }
    }
    
    staticvoidMain(string[]args)
    {
      ThreadStartchildref=newThreadStart(CallToChildThread);
      Console.WriteLine("InMain:CreatingtheChildthread");
      ThreadchildThread=newThread(childref);
      childThread.Start();
      //停止主线程一段时间
      Thread.Sleep(2000);
      //现在中止子线程
      Console.WriteLine("InMain:AbortingtheChildthread");
      childThread.Abort();
      Console.ReadKey();
    }
  }
}

当上面的代码被编译和执行时,它会产生下列结果:

InMain:CreatingtheChildthread Childthreadstarts 0 1 2 InMain:AbortingtheChildthread ThreadAbortException Couldn’tcatchtheThreadException

标签: 线程 多线程

C# 不安全代码

WSDL 教程

上述就是C#学习教程:C# 多线程分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/908496.html

(0)
上一篇 2021年10月25日
下一篇 2021年10月25日

精彩推荐