您的位置:首页 > 编程语言 > C#

C#多线程基础

2015-04-26 21:29 169 查看
核心内容:
1、必要的空间引入。
2、在当前线程上新建另一线程。
3、运行线程。
4、挂起线程。
5、线程恢复。
6、线程等待。
7、线程同步。
8、线程异步。
9、结束线程。

具体实现:
1、(必须)引入System.Threading空间。
2、C#中几乎所的都被封装成类,Thread也是如此,采取类的实例化(定义方式)。
要注意的是构造函数Thread()的参数。参数实质是一个方法。既可以先用委托也可直接放方法实例
自带的ParameterizedThreadStart委托是一种只有object类型的数组参数(即不能有out,ref参数),
必须没有返回值。
注:先来深入理解一下【同一个进程中所有线程共享资源】这句话的含义:C#是面向对象的,
一切皆对象,那么共享就是对各个对象的访问与操作。而新建线程则需要通过函数而构造所以
必须遵循类与类的访问限制。这里先不必关注主线程是怎样访问类的私有成员的(他必须具有这个能力,否则
程序怎么执行呢?)
在类中,特别注意,如果类未被实例化,那么,被线程调用的函数就不能运行,除非使用静态函数或实例化,在控制台特别要注意
。或者先实例化这个类(这是非常困难的,构造函数是要通过
new 来调用,而Thread()的参数只能是方法不能是new 之类的语句)。
3、新建线程后并没有运行,需要用 [线程名].Start() 参数就为所调用方法的参数(没有就不填)。
4、挂起线程、恢复、等待、同步,一般不用不采用 [实例].Suspend();与恢复 [实例].Resume();
而是使用AutoResetEvent类,其允许线程通过发信号互相通信。(该代码相当于“模式窗体”,其状态为False则停止不去执行下面的
代码)通常,此通信涉及线程需要独占访问的资源。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,
并等待当前控制资源的线程
通过调用 Set 发出资源可用的信号。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。
可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。
通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,
WaitOne是等待信号,只有发了信号,
等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。
以此来实现线程的控制(挂起与恢复)以及进程间通信(等待、同步)。
还可以使用Join(),把一个进程插入另一个进程,
例如在B中建立A,在执行 A.Join(); 表示B先停止等待一下A,(但记住:对A没有影响),也可以指定时间,如果不指定,则直到
A执行完。(线程同步技术)
5、线程异步,在创建之后各个线程就是异步的
Join()方法
6、线程结束,调用的的函数执行完就处与结束状态,也可以调用Abrot(),但不一定能停下来;

几个重要属性:
(1)ThreadState(只读)---ThreadState的枚举
Abroted :表示线程代码尚未执行完但却被强行退出(停止)
AbrotRequested : 表示已调用abrot(),但尚未停止。
Background :表示后台线程
Background:线程在后台执行,与属性Thread.IsBackground有关;
Running:线程正在正常运行;
Stopped:线程已经被停止;
StopRequested:线程正在被要求停止;
Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);
SuspendRequested:线程正在要求被挂起,但是未来得及响应;
Unstarted:未调用Thread.Start()开始线程的运行;
WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;

(2)IsAlive(只读)---表示是否在运行代码(暂停,未开始,挂起,等待都处于未活动状态)
(3)isBackground(可写----表示是否是后台程序
(4)Priority(可写)--------优先级,ThreadPriority的枚举,CPU分配给线程的时间多少。
AboveNormal
BelowNormal
Highest
Lowest
Normal
关系:Lowest < BelowNormal < Normal < AboveNormal < Highest

-------------------------------------------------------------代码实现--------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;      //注:这里是要自己引入的

namespace ConsoleApplication1
{
class Program
{
private static AutoResetEvent a;
static void Main(string[] args)
{
Thread th1 = new Thread(thread1);
Thread th3 = new Thread(new ThreadStart(thread3));

Console.WriteLine("------------------------第已种方法:Join()阻塞---------------");
th1.Start();
th1.Join();    //直到1执行完主线程才继续
th1.Abort();   //再加一道“保险”

Console.WriteLine("------------------------第二种方法:基于AutoResetEvent消息传送机制---------------");
a = new AutoResetEvent(true);    //指示新建的开始状态”机制“是否导通。
//其实在这设置更好,但为了体现用法,此处的true相当于set();
th3.Start();

Console.ReadLine();
}

/// <summary>
/// 实现join()用法
/// </summary>
private static void thread1() {            //第一的线程要运行的实例
Console.WriteLine("线程1开始运行");
Thread th2 = new Thread(new ParameterizedThreadStart(thread2));
th2.Start(5);
Console.WriteLine("线程1将要等待2");
th2.Join();                             //在异步的状况下只有2执行完,才继续执行
Console.WriteLine("线程1继续运行");
th2.Abort();                            // 确保不影响下面一种方法的输出时不受干扰
}

private static void thread2(object n)       //第一的线程要运行的实例
{
Console.WriteLine("线程2开始运行" + ",并传入了参数" + ((int)n).ToString());
Console.WriteLine("线程2将要休眠2s");
Thread.Sleep(2000);
Console.WriteLine("线程2继续运行");
}
/// <summary>
/// 实现AutoResetEvent用法
/// </summary>
private static void thread3()  //第三个线程实例
{
a.Reset();
Console.WriteLine("线程3开始在运行");
Thread th4 = new Thread(thread4);
th4.Start();
Console.WriteLine("线程3将要等待4");
a.WaitOne();
Console.WriteLine("线程3恢复运行");
}
private static void thread4() {
Console.WriteLine("线程4开始在运行");
Console.WriteLine("线程4将要停止1s");
Thread.Sleep(1000);
Console.WriteLine("线程4恢复运行");
a.Set();
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: