.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(DateTime.Now.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中,控件绑定到特定的线程,从另一个线程更新控件,不应该直接调用该控件的成员,这个非常有用,下篇博文讲。

资源下载