c# 多线程学习(一)

 

今天回顾了一下c#的多线程机制。平时写程序很少写多线程的,因此我也感觉以前的程序都很低级。

没使用过多线程的时候,对它的机制很好奇。它究竟是怎么执行的呢?从什么地方冒出另外一个线程的? 其实我现在认为,就是另开了一个线程,执行某个函数。注意重点,“执行某个函数”。

目前我知道有两种方式实现多线程编程: thread类 和 委托线程

一、使用thread 类

  

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace ConsoleTest
 8 {
 9     class Program
10     {
11         public static void TaskThread()
12         {
13             Console.WriteLine("thread running.");
14             Thread.Sleep(5000);
15             Console.WriteLine("thread finish.");
16         }
17 
18         public static void Main(string[] args)
19         {
20             Thread thread = new Thread(TaskThread);
21             thread.IsBackground = true;
22             thread.Start();
23             Console.WriteLine("main finish");
24         }
25     }
26 }

既然是初学,自然是举很简单的例子了。 thread的构造函数里面是一个void类型无参数的函数。注意到里面有一行代码:

1  thread.IsBackground = true;

thread 创建的线程默认是前台线程,就是说,只要有一个线程没有执行完,程序就不会退出。但是把 IsBackground 设置为 true 之后,只要其他的前台线程结束了,不管后台线程是否完毕,进程都会退出。

可以在线程里加入参数。

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace ConsoleTest
 8 {
 9 
10     class Parameter
11     {
12        public  string words ;
13     }
14 
15     class Program
16     {
17         public static void TaskThread(object o)
18         {
19             Console.WriteLine("thread running.");
20             Thread.Sleep(1000);
21             Console.WriteLine(((Parameter)o).words);
22             Console.WriteLine("thread finish.");
23         }
24 
25         public static void Main(string[] args)
26         {
27             Thread thread = new Thread(TaskThread);
28             thread.Start(new Parameter() { words = "lianjx should study hard and marry 00 in the near feature." });
29             Console.WriteLine("main finish");
30             Console.ReadKey();
31         }
32     }
33 }

thread有一些方法可以控制线程,如Abort(),Join(),Resume().
还可以用线程池,线程池里的线程都是后台线程

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace ConsoleTest
 8 {
 9 
10     class Parameter
11     {
12        public  string words ;
13     }
14 
15     class Program
16     {
17         public static void TaskThread(object o)
18         {
19             Console.WriteLine("thread running.");
20             Thread.Sleep(1000);
21             Console.WriteLine("thread finish.");
22         }
23 
24         public static void Main(string[] args)
25         {
26             for (int i = 0; i < 5; i++)
27             {
28                 ThreadPool.QueueUserWorkItem(TaskThread);
29             }
30 
31             Console.ReadKey();
32         }
33     }

二、创建线程的另一种方式是委托。

View Code
 1 class Program
 2     {
 3         public static float newTask(int ms)
 4         {
 5             Console.WriteLine("new task begins. test thread");
 6             Thread.Sleep(4000);
 7 
 8             Console.WriteLine("thread {0} finish",ms);
 9 
10             return ms;
11         }
12 
13         public delegate float NewTaskDelegate(int ms);
14 
15         public static void Main(string[] args)
16         {
17             NewTaskDelegate task1 = newTask;
18             NewTaskDelegate task2 = newTask;
19 
20             IAsyncResult result1 = task1.BeginInvoke(1, null, null);
21             IAsyncResult result2 = task2.BeginInvoke(2, null, null);
22 
23 
24             // 等到两个线程都执行完毕之后才结束循环
25             int finish = 0;
26             while (true)
27             {
28                 if (result1.IsCompleted)
29                     finish = finish | 1;
30                 if (result2.IsCompleted)
31                     finish = finish | 2;
32                 if (finish == 3)
33                     break;
34             }
35 
36             Console.WriteLine("Now get result...");
37             Console.WriteLine("{0}\t{1}",task1.EndInvoke(result1),task2.EndInvoke(result2));
38             Console.ReadKey();
39         }
40     }

关键是委托函数的BeginInvoke 和EndInvoke 。 BeginInvoke()的最后两个参数是回调用的,委托建立线程有很多技巧和这两个参数有关,这里不多说。
一旦执行BeginInvoke,就在后台开了一个线程,主函数Main执行到EndInvoke(),如果线程没有执行完毕,那么主函数会一直阻塞等待。所以在EndInvoke之前,通过IAsyncResult 携带的线程信息来确定是否执行完毕,以免程序陷入假死的状态。

posted on 2012-07-26 19:01  leavingseason  阅读(1322)  评论(0编辑  收藏  举报

导航

Bye!