using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//C#多线程
/*
* 线程的生命周期
* 线程生命周期开始于System.Threading.Thread类的对象被创建时,结束于线程被终止或完成执行时。
* 各种状态:
* 未启动状态:当线程实例被创建但Start方法未被调用时的状态
* 就绪状态:当线程准备好运行并等待CPU周期时的状态
* 不可运行状态:包含下面几种情况
* 已经调用Sleep方法
* 已经调用Wait方法
* 通过I/O操作阻塞
* 死亡状态:当线程已完成指向或已中止时的状态
*/
//主线程
/*
* System.Threading.Thread类用于线程的工作。它允许创建并访问多线程应用程序中的单个线程。进程中第一个被执行的线程称为主线程。
* 当C#程序开始执行时,主线程自动创建。使用Thread类创建的线程被主线程的子线程调用。你可以使用Thread类的CurrrentThread属性访问线程。
*/
Thread th1 = Thread.CurrentThread;
th1.Name = "MainThread";
Console.WriteLine("This is {0}", th1.Name);
/*
* Thread类常用属性
* CurrentContext获取线程正在其中执行的当前上下文
* CurrentCulture获取或设置当前线程的区域性
* CurrentPrincipal获取或设置线程的当前负责人(对基于角色的安全性而言)
* CurrentThread获取当前正在允许的线程
* CurrentUICulture获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源
* ExecutionContext获取一个ExecutionContext对象,该对象包含有关当前程序的各种上下文的信息
* IsAlive获取一个值,该值指示当前线程的执行状态
* IsBackground获取或设置一个值,该值指示某个线程是否为后台线程
* IsThreadPoolThread获取一个值,该值指示线程是否属于托管线程池
* ManagedThreadId获取当前托管线程的唯一标识符
* Name获取或设置线程的名称
* Priority获取或设置一个值,该值指示线程的调度优先级
* ThreadState获取一个值,该值包含当前线程的状态
*
* Thread类常用方法
* public void Abort()在调用此方法的线程上引发ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。
* public static LocalDataStoreSlot AllocateDataSlot()在所有线程上分配未命名的数据槽。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。
* public static LocalDataStoreSlot AllocateNamedDataSlot(string name)在所有线程上分配已命名的数据槽。为了更好的性能,请改用以ThreadStaticAttribute属性标记的字段。
* public static void BeginCriticalRegion()通知主机执行将要进入一个代码区域,在该代码区域内线程终止或未经处理的异常的影响可能会危害应用程序域中的其他任务。
* public static void BeginThreadAffinity()通知主机托管代码将要执行依赖于当前物理操作系统线程的标识的指令
* public static void EndCritialRegion()通知主机执行将要进入一个代码区域,在该代码区域内线程终止或未经处理的异常仅影响当前任务
* public static void FreeNamedDataSlot(string name)为进程中的所有线程消除名称与槽之间的关联。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段。
* public static Object GetData(LocalDataStoreSlot slot)在当前线程的当前域中从当前线程上指定的槽中检索值。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段
* public static AppDomain GetDomain()返回当前线程正在其中运行的当前域
* public static AppDomain GetDomainID()返回唯一的应用程序域标识符
* public static LocalDataStoreSlot GetNamedDataSlot(string name)查找已命名的数据槽。为了获得更好的性能,请改用以ThreadStaticAttribute属性标记的字段
* public void Interrupt()中断处于WaitSleepJoin线程状态的线程
* public void Join()在继续执行标准的COM和SendMessage消息泵处理期间,阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式。
* public static void MemoryBarrier()按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行MemoryBarrier调用之后的内存存取,再执行MemoryBarrier调用之前的内存存取的方式。
* public static void ResetAbort()取消为当前线程请求的Abort
* public static void SetData(LocalDataStoreSlot slot, Object data)在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以ThreadStaticAttribute属性标注的字段。
* public void Start()开始一个线程
* public static void Sleep(int millisecondsTimeout)让线程暂停一段事件
* public static void SpinWait(int iterations)导致线程等待由iterations参数定义的时间量
* public static byte VolatileRead(ref byte address)
* public static double VolatileRead(ref double address)
* public static int VolatileRead(ref int address)
* public static Object VolatileRead(ref Object address)
* 读取字段值。无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。此方法有不同的重载形式。这里只给出了一些形式
* public static void VolatileWrite(ref byte address, byte value)
* public static void VolatileWrite(ref double address, double value)
* public static void VolatileWrite(ref int address, int value)
* public static void VolatileWrite(ref Object address, Object value)
* 立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。此方法有不同的重载形式。这里只列出一些
* public static bool Yield()导致调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程
*/
//创建线程
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
//管理线程
/*
* Thread类提供了各种管理线程的方法
* 下面的实例演示了sleep()方法的使用,用于在一个特定的时间暂停线程
*/
ThreadStart childref2 = new ThreadStart(CallToChildThread2);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread2 = new Thread(childref2);
childThread2.Start();
//销毁线程
/*
* Abort()方法用于销毁线程
* 通过抛出threadabortException在运行时中止线程。这个异常不能被捕获,如果有finally块,控制会被送至finally块。
*/
ThreadStart childref3 = new ThreadStart(CallToChildThread3);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread3 = new Thread(childref3);
childThread3.Start();
//停止主线程一段时间
Thread.Sleep(2000);
//现在中止子线程
Console.WriteLine("In Main: Aborting the Child thread");
childThread3.Abort();
Console.ReadKey();
}
public static void CallToChildThread3()
{
try
{
Console.WriteLine("child thread starts");
//计数到10
for(int counter = 0;counter <= 10;counter++)
{
Thread.Sleep(500);
Console.WriteLine(counter);
}
Console.WriteLine("child thread completed");
}catch(ThreadAbortException e)
{
Console.WriteLine("Thread Abort Exception");
}finally
{
Console.WriteLine("could not catch the thread exception");
}
}
public static void CallToChildThread2()
{
Console.WriteLine("Child thread starts");
//线程暂停5000ms
int sleepfor = 5000;
Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
Thread.Sleep(sleepfor);
Console.WriteLine("Child thread resumes");
}
public static void CallToChildThread()
{
Console.WriteLine("Child thread starts");
}
}
}