浅谈C#多线程简单例子讲解

2019-12-30 14:52:30于海丽

此代码产生的输出类似如下内容:


Main thread: Start a second thread.
Main thread: Do some work.
ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Call Join(), to wait until ThreadProc ends.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
Main thread: ThreadProc.Join has returned. Press Enter to end program.

在Visul C#中System.Threading 命名空间提供一些使得可以进行多线程编程的类和接口,其中线程的创建有以下三种方法:Thread、ThreadPool、Timer。下面就它们的使用方法逐个作一简单介绍。

一、Thread

这也许是最复杂的方法,但它提供了对线程的各种灵活控制。首先你必须使用它的构造函数创建一个线程实例,它的参数比较简单,只有一个ThreadStart 委托:public Thread(ThreadStart start);然后调用Start()启动它,当然你可以利用它的Priority属性来设置或获得它的运行优先级(enum ThreadPriority: Normal、 Lowest、 Highest、 BelowNormal、 AboveNormal)。

下例首先生成了两个线程实例t1和t2,然后分别设置它们的优先级,接着启动两线程(两线程基本一样,只不过它们输出不一样,t1为“1”,t2为“2”,根据它们各自输出字符个数比可大致看出它们占用CPU时间之比,这也反映出了它们各自的优先级)。


static void Main(string[] args)
{
 Thread t1 = new Thread(new ThreadStart(Thread1));
 Thread t2 = new Thread(new ThreadStart(Thread2));

 t1.Priority = ThreadPriority.BelowNormal ;
 t2.Priority = ThreadPriority.Lowest ;
   t1.Start();
  t2.Start();
 }
public static void Thread1()
{ 
 for (int i = 1; i < 1000; i++) 
 {//每运行一个循环就写一个“1”
  dosth();
 Console.Write("1");
 }
 }
public static void Thread2()
{ 
 for (int i = 0; i < 1000; i++) 
 {//每运行一个循环就写一个“2”
 dosth();
 Console.Write("2");
 }
}
public static void dosth()
{//用来模拟复杂运算
 for (int j = 0; j < 10000000; j++) 
 { 
 int a=15;
 a = a*a*a*a;
 }
}

以上程序运行结果为:

11111111111111111111111111111111111111111121111111111111111111111111111111111111111112
11111111111111111111111111111111111111111121111111111111111111111111111111111111111112
11111111111111111111111111111111111111111121111111111111111111111111111111111111111112

从以上结果我们可以看出,t1线程所占用CPU的时间远比t2的多,这是因为t1的优先级比t2的高,若我们把t1和t2的优先级都设为Normal,结果见下:

121211221212121212121212121212121212121212121212121212121212121212121
212121212121212121212121212121212121212121212121212121212121212121212
121212121212121212

从上例我们可看出,它的构造类似于win32的工作线程,但更加简单,只需把线程要调用的函数作为委托,然后把委托作为参数构造线程实例即可。当调用Start()启动后,便会调用相应的函数,从那函数第一行开始执行。