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 之后,只要其他的前台线程结束了,不管后台线程是否完毕,进程都会退出。
可以在线程里加入参数。
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().
还可以用线程池,线程池里的线程都是后台线程
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 }
二、创建线程的另一种方式是委托。
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) 编辑 收藏 举报