多线程
线程(从机器的
CPU
角度看)一个线程是程序执行的一个单独过程。一个线程不能够被任何底层的事件中断,并且不包括执行更小的过程。
在
.NET
中,多线程功能是在
System.Threading
名称空间中定义的。因此,在使用任何线程类之前,必须定义
System.Threading
名称空间。其结构图如下:
Thread
类主要属性和方法
属
性
|
说
明
|
CurrentThread
|
获取当前正在运行的线程
|
IsAlive
|
获取表示当前线程执行状态的值。
如果此线程已启动并且尚未正常终止或中止,则为
true
;否则为
false
。
|
Name
|
获取或设置线程的名称
|
Priority
|
获取或设置表示线程调度的优先级的值。
Priority
是一个枚举值。
(
1
)
Highest
:最高级别
(
2
)
AboveNormal
:该线程安排在
Highest
之后,
Normal
之前。
(
3
)
Normal
:该线程安排在
AboveNormal
之后,
BelowNormal
之前。默认为
Normal
。
(
4
)
BelowNormal
:该线程安排在
Normal
之后,
Lowest
之前。
(
5
)
Lowest
:最低级别
注意:在安排线程的优先级之前,线程的状态必须为运行。
|
ThreadState
|
获取包含当前线程的状态的值。
ThreadState
是一个枚举值。
|
方
法
|
说
明
|
Start()
|
使操作系统当前实例的状态更改为
ThreadState.Running
|
Sleep()
|
禁止线程运行的毫秒数
|
Interrupt()
|
中止处于
Sleep
或
Join
线程状态的线程
|
Abort()
|
调用该方法终止线程
Thread 类的 Abort 方法用于永久地杀死一个线程。但是请注意,在调用 Abort 方法前一定要判断线程是否被激活,也就是判断 thread.IsAlive 的值:
if ( thread.IsAlive )
{ thread.Abort(); }
|
Join()
|
禁止调用线程,直至线程终止
|
Suppend()
|
挂起线程,如果线程已挂起,则方法无效。
Thread
类的
Suspend
方法可以
挂起
一个线程。线程被
挂起
到调用
Resume
方法为止。
if (thread.ThreadState = ThreadState.Running )
{ thread.Suspend(); }
|
Resume()
|
恢复被挂起的线程。
调用
Resume
方法可以恢复一个被
挂起
的线程。如果线程没有被
挂起
,
Resume
方法就是无效的。
if (thread.ThreadState = ThreadState.Suspended )
{ thread.Resume(); }
|
创建线程语法:
Thread
线程实例名称=new Thread(new ThreadStart(方法名称))
线程同步
C#
提供了锁定机制,也称线程同步。
线程同步的意思是指单独的线程执行不被其他的线程所干扰,要执行下一个线程必须等该线程结束才能进行。这样才能保证多个线程输出的一致和同步。
线程同步是确保不同的线程对共享资源(如控制台)进行协调访问的一种方法。C#中通过lock关键字提供同步。锁定机制确保每次只有一个线程访问方法或代码,除非它已经完成了对方法或代码的执行,否则其他线程就无法进行访问。当两个或两个以上的线程试图访问一个共享资源或共享文件时,这种机制尤其有用。
using
System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadDemo
... {
class Program
...{
static void Main(string[] args)
...{
Thread.CurrentThread.Name = "主线程";
Program prg = new Program();
Thread objThread = new Thread(prg.ActionMethod);
objThread.Name = "子线程";
objThread.Start();
}
void ActionMethod()
...{
//lock关键字用于锁定此线程.
lock (this)
...{
for (int count = 1; count <= 10; count++)
...{
if (count == 5)
...{
Thread.Sleep(2000);
}
else
...{
Console.WriteLine("线程名: " + Thread.CurrentThread.Name + count.ToString());
}
}
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadDemo
... {
class Program
...{
static void Main(string[] args)
...{
Thread.CurrentThread.Name = "主线程";
Program prg = new Program();
Thread objThread = new Thread(prg.ActionMethod);
objThread.Name = "子线程";
objThread.Start();
}
void ActionMethod()
...{
//lock关键字用于锁定此线程.
lock (this)
...{
for (int count = 1; count <= 10; count++)
...{
if (count == 5)
...{
Thread.Sleep(2000);
}
else
...{
Console.WriteLine("线程名: " + Thread.CurrentThread.Name + count.ToString());
}
}
}
}
}
}
后台线程
比起应用程序的主图形用户界面(
GUI
)线程来说,这些线程以较低的优先权在不同的过程中运行着。对于不能立即执行结束,又不想一直等待的任务,后台线程能很好的胜任。在
C#
中,把线程对象的
IsBackground
属性设为
true
,该线程即为后台线程。
注意:后台线程不能直接操作所在进程之外的数据引用。
怎样与后台线程通讯?运用
MethodInvoker
委托实体。
要使用
MethodInvoker
委托,需要三个条件:
1
一个创建委托的后台线程
Thread fThread=new Thread(new ThreadStart(ThreadFunc));
fThread.IsBackground=true;
fThread.Start();
2
一个用作后台线程与前台可视化单元的接口的类级方法
public void ThreadFunc()
{
try
{
MethodInvoker mi=new MethodInvoker(this.UpdateLabel);
while(true)
{
bCounter++;
this.BeginInvok(mi);
Thread.Sleep(500);
}
}
catch(ThreadInterruptedException e)
{
Console.WriteLine("Interruption Exception in Thread:{0}",e);
}
catch(Exception we)
{
Console.WriteLine("Exception in Thread:{0}",we);
}
}
3
一个应用程序中可以更新的可视化单元
public void UpdateLabel()
{
label1.Text=bCounter.ToString();
}
后台线程源工程:http://download.csdn.net/source/369047
线程优先级示例:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadDemo
... {
class Program
...{
static void Main(string[] args)
...{
Program prg=new Program();
Thread threadOne = new Thread(new ThreadStart(prg.TaskOne));
Thread threadTwo =new Thread(new ThreadStart(prg.TaskTwo));
threadOne.Priority = ThreadPriority.Lowest;
threadOne.Start();
threadTwo.Start();
}
void TaskOne()
...{
for (int count = 1; count < 5; count++)
...{
Console.WriteLine("TaskOne:"+count*2);
}
}
void TaskTwo()
...{
for (int index = 5000; index >=4990; index--)
...{
Console.WriteLine("TaskTwo:" + index);
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadDemo
... {
class Program
...{
static void Main(string[] args)
...{
Program prg=new Program();
Thread threadOne = new Thread(new ThreadStart(prg.TaskOne));
Thread threadTwo =new Thread(new ThreadStart(prg.TaskTwo));
threadOne.Priority = ThreadPriority.Lowest;
threadOne.Start();
threadTwo.Start();
}
void TaskOne()
...{
for (int count = 1; count < 5; count++)
...{
Console.WriteLine("TaskOne:"+count*2);
}
}
void TaskTwo()
...{
for (int index = 5000; index >=4990; index--)
...{
Console.WriteLine("TaskTwo:" + index);
}
}
}
}