基于.NET的多线程编程入门

2016-02-19 14:13 1 1 收藏

今天天气好晴朗处处好风光,好天气好开始,图老师又来和大家分享啦。下面给大家推荐基于.NET的多线程编程入门,希望大家看完后也有个好心情,快快行动吧!

【 tulaoshi.com - 编程语言 】

       什么是线程?

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

  什么是多线程?

  多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率。线程是在同一时间需要完成多项任务的时候被实现的。

  使用线程的好处有以下几点:

  使用线程可以把占据长时间的程序中的任务放到后台去处理

  用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度

  程序的运行速度可能加快

  在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较游泳了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

  还有其他很多使用多线程的好处,这里就不一一说明了。

  一些线程模型的背景

  我们可以重点讨论一下在Win32环境中常用的一些模型。

  单线程模型

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

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

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

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

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

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

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

  创建线程:

  创建一个新的Thread对象的实例。Thread的构造函数接受一个参数:

 

Thread DummyThread = new Thread( new ThreadStart(dummyFunction) );


  执行线程:

  使用Threading命名空间里的start方法来运行线程:

 

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/) DummyThread.Start ();


  组合线程:

  经常会出现需要组合多个线程的情况,就是当某个线程需要其他线程的结束来完成自己的任务。假设DummyThread必须等待DummyPriorityThread来完成自己的任务,我们只需要这样做:

 

DummyPriorityThread.Join() ;


  暂停线程:

  使得线程暂停给定的秒

 

DummyPriorityThread.Sleep(Time in Second);


  中止线程:

  如果需要中止线程可以使用如下的代码:

 

DummyPriorityThread.Abort();


  同步

  经常我们会遇到需要在线程间进行同步的情况,下面的代码给出了一些方法:

 

using System;using System.Threading;namespace SynchronizationThreadsExample{
 class SynchronizationThreadsExample{
  private int counter = 0;
  static void Main( ) {
   SynchronizationThreadsExample STE = new SynchronizationThreadsExample();
   STE.ThreadFunction( );
  }
  public void ThreadFunction ( ) {
   Thread DummyThread = new Thread( new ThreadStart(SomeFunction) ;
   DummyThread.IsBackground=true;
   DummyThread.Name = "First Thread";
   DummyThread.Start( );
   Console.WriteLine("Started thread {0}", DummyThread.Name);
   Thread DummyPriorityThread = new Thread( new ThreadStart(SomeFunction) );
   DummyPriorityThread.IsBackground=true;
   DummyPriorityThread.Name = "Second Thread";
   DummyPriorityThread.Start( );
   Console.WriteLine("Started thread {0}", DummyPriorityThread.Name);
   DummyThread.Join( );
   DummyPriorityThread.Join( );
  }
  public void SomeFunction( ) {
   try {
    while (counter 10) {
     int tempCounter = counter;
     tempCounter ++;
     Thread.Sleep(1);
     counter = tempCounter;
     Console.WriteLine( "Thread {0}. SomeFunction: {1}",Thread.CurrentThread.Name, counter);
    }
   }
   catch (ThreadInterruptedException Ex) {
    Console.WriteLine( "Exception in thread {0} ", Thread.CurrentThread.Name);
   }
   finally {
    Console.WriteLine( "Thread {0} Exiting. ",Thread.CurrentThread.Name);
   }
  }
 }
}


  使用Interlock

  C#提供了一个特殊的类叫做interlocked,就是提供了锁机制的实现,我们可以加入如下的代码实现锁机制:

 

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/) Interlocked.SomeFunction (ref counter);


  使用锁

  这是为了锁定代码关键区域以进行同步,锁定代码如下:

 

lock (this){ Some statements ;}


  使用Monitor

  当有需要进行线程管理的时候我们可以使用:

 

Monitor.Enter(this);


  其他也有一些方法进行管理,这里就不一一提及了。

  线程的缺点

  线程自然也有缺点,以下列出了一些:

  如果有大量的线程,会影响性能,因为操作系统需要在他们之间切换;

  更多的线程需要更多的内存空间

  线程会给程序带来更多的bug,因此要小心使用

  线程的中止需要考虑其对程序运行的影响

  通常块模型数据是在多个线程间共享的,需要一个合适的锁系统替换掉数据共享
 

来源:https://www.tulaoshi.com/n/20160219/1606478.html

延伸阅读
标签: Java JAVA基础
在 Java 程序中使用多线程要比在 C 或 C++ 中容易得多,这是因为 Java 编程语言提供了语言级的支持。本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观。读完本文以后,用户应该能够编写简单的多线程程序。 为什么会排队等待? 下面的这个简单的 Java 程序完成四项不相关的任务。这样的程序有单个控制...
前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验。我们务必要把耗时的操作放到别的线程中去执行,千万不要阻塞主线程。 iOS中有以下3种多线程编程方法: NSThreadGrand Centeral Dispatch(GCD)NSOperation和NSOperationQueue 1.NSThread 这是最轻量级的多线程的方法,使用起来最直观的多线程编程方法。但是...
标签: Java JAVA基础
不提倡使用的方法是为支持向后兼容性而保留的那些方法,它们在以后的版本中可能出现,也可能不出现。Java 多线程支持在版本 1.1 和版本 1.2 中做了重大修订,stop()、suspend() 和 resume() 函数已不提倡使用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听起来很诱人,但请抵制诱惑不要使用它们。 调试线程化...
标签: Java JAVA基础
线程组 线程是被个别创建的,但可以将它们归类到线程组中,以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中,使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。 线程间发信 当线程在继续执行前需要等待一个条件时,仅有 synchronized ...
当一个线程进入wait之后,就必须等其他线程notify/notifyall,使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。注意,任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码,notifyall只是让处于wait的线程重新拥有锁的争夺权,但是只会有一个获得锁并执行...

经验教程

468

收藏

85
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部