.NET多线程执行函数
[来源] 达内 [编辑] 达内 [时间]2012-11-12
原因是DebugLZQ在写一个LINQ综合Demo的时候遇到了多线
前面几篇文章一直在写LINQ,这里为什么会出现多线程?原因是De bugLZQ在写一个LINQ综合Demo的时候遇到了多线程,便停下手来整理一下。关于多线程的文章,园子里很多很多,因此关于多线程理论性的东西,LZ就不去多说了,这篇博文主要是用最简单的例子,总结下多线程调用函数的相关注意点,重点偏向应用和记忆。
1.多线程 用无参函数
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 多线程 { class Program { static void Main(string [] args) { Console.WriteLine( " 主线程开始" ); Thread t = new Thread(new ThreadStart(ShowTime)); // 注意ThreadStart委托的定义形式 t.Start();// 线程开始,控制权返回Main线程 Console.WriteLine(" 主线程继续执行" ); // while (t.IsAlive == true) ; Thread.Sleep(1000 ); t.Abort(); t.Join();// 阻塞Main线程,直到t终止 Console.WriteLine(" --------------" ); Console.ReadKey(); } static void ShowTime() { while (true ) { Console.WriteLine(.ToString()); } } } }
注意ThreadStart委托的定义如下:
可见其对传递进来的函数要求是:返回值void,无参数。
2.多线程 用带参函数(两种方法)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 多线程2_带参数 { class Program { static void Main(string [] args) { Console.WriteLine( " Main线程开始" ); Thread t = new Thread(new ParameterizedThreadStart(DoSomething));// 注意ParameterizedThreadStart委托的定义形式 t.Start(new string[]{"Hello "," World" }); Console.WriteLine( " Main线程继续执行" ); Thread.Sleep( 1000 ); t.Abort(); t.Join(); // 阻塞Main线程,直到t终止 Console.ReadKey(); } static void DoSomething(object s) { string[] strs = s as string[]; while (true ) { Console.WriteLine(" {0}--{1}",strs[0],strs[1 ]); } } } }
注意ParameterizedThreadStart委托的定义如下:
可见其对传入函数的要求是:返回值void,参数个数1,参数类型object
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 多线程2_带参数2 { class Program { static void Main(string [] args) { Guest guest = new Guest() { Name =" Hello" , Age=99 }; Thread t = new Thread(new ThreadStart(guest.DoSomething));// 注意ThreadStart委托的定义形式 t.Start(); Thread.Sleep( 1000 ); t.Abort(); t.Join(); // 阻塞Main线程,直到t终止 Console.ReadKey(); } } // class Guest { public string Name { get; set ; } public int Age { get ; set; } public void DoSomething() { while (true ) { Console.WriteLine( "{0}--{1} " , Name, Age); } } } }
这个还是使用ThreadStart委托,对方法进行了一个封装。
两种方法,可随意选择,第一种貌似简洁一点。
3.线程同
线程同步的方法有很多很多种volatile、Lock、InterLock、Monitor、Mutex、ReadWriteLock...
这里用lock说明问题:在哪里同步,用什么同步,同步谁?
首先感受下不同步会出现的问题:
代码就是下面的代码去掉lock块。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 多线程3_同步2 { class Program { static object obj = new object();// 同步用 static int balance = 500; static void Main(string [] args) { Thread t1 = new Thread(new ThreadStart(Credit)); t1.Start(); Thread t2 = new Thread(new ThreadStart(Debit)); t2.Start(); Console.ReadKey(); } static void Credit() { for (int i = 0; i < 15 ; i++) { lock (obj) { balance += 100 ; Console.WriteLine( " After crediting,balance is {0} " , balance); } } } static void Debit() { for (int i = 0; i < 15 ; i++) { lock (obj) { balance -= 100; Console.WriteLine( " After debiting,balance is {0} " , balance); } } } } }
小结:多线程调用函数就是这样。在Winform中,控件绑定到特定的线程,从另一个线程更新控件,不应该直接调用该控件的成员,这个非常有用,下篇博文讲。