.net系统自学笔记——线程,任务和同步

一、线程

线程是程序中独立的指令流。进程包含资源。每个进程都分配了虚拟内在,一个进程至少包含一个线程。操作系统会调度线程。线程有一个优先级、实际上正在处理的程序的位置计数器、一个存储其局部变量的栈。每个线程都有自己的栈,但程序代码的内存和堆由一个进程的所有线程共享。这使一个进程的所有线程之间的通信非常快,该进程的所有线程都寻址相同的虚拟内存。缺点是多个线程可以修改同一个内存位置。进程管理的资源包括虚拟内存和Windows句柄。其中至少包含一个线程。线程是运行程序所必需的。

二、异步委托

创建线程的一种简单方式是定义一个委托,并异步调用它。Delegate类还支持异步地调用方法,在后台,Delegate会创建一个执行任务的线程(委托使用纯种池来完成异步任务)

方法1:投票:一种技术是投票,并检查委托是否完成了它的任务。Delegate类提供了BeginInvoke()方法和EndInvoke()方法。BeginInvoke()方法 总是有AsyncCallback和Object类型的两个额外参数,而返回类型是IAsyncResult。通过IAsyncResult,可以获得该委托的相关信息,并验证委托是否完成了任务,用IsCompleted属性。EndInvoke()方法会一直等待,直到委托完成其任务为止。如果在委托结束之前不等待委托完成其任务就结束主线程,委托线程就会停止。

方法2:等待句柄:等待异步委托的结果的另一种方式是使用与IAsyncResult相关联的等待句柄。使用AsyncWaitHandle属性可以访问等待句柄。这个属性返回一个WaitHandle类型的对象,它可以等待委托纯种完成其任务。WaitOne()方法将一个超时时间作为可选 的第一个参数。在其中可以定义要等待的最长时间。如果发生超时,WaitOne()方法就返回False.

方法3:异步回调:在BeginInvoke()方法的第三个参数中,可以传递一个满足AsyncCallback委托的需求的方法,即一个IAsyncResult类型的参数,返回类型是void。使用回调方法必须注意这个方法从委托线程中调用,而不是从主线程中调用。也可用Lambda静态式来表示这种情况。

以上三种方法不仅能适用于委托,同样适用于.net Framework 中其他的异步模式。

三、Thread类

除了使用委托创建线程外,还可以用Thread类创建线程,和控制线程。Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。ThreadStart委托定义了一个返回类型为void的无参数方法。在创建了对象后,可以用Start()方法启动线程。线程由操作系统调度。Lambda表达式也可以与Thread类一起使用。

1.给线程传递数据:

一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数,另一种方式是创建一个自定义类,把纯种的方法定义为实例方法,这样就可以初始化实例的数据,之后启动线程。如果使用 了ParameterizedThreadStart委 托 ,线 程 的入 口点必须有一个Object类 型的参数 ,且 返回类型为 viod。 对象可 以强制转换为任意数据类型.

2.后台线程:默认情况下,Thread类伊娃的线程是前台线程。线程池中的线程总是后台线程。也可以在用Thread类创建线程时,设置IsBackground属性,以确定该线程是前台还是后台。后台线程非常适合于完成后台任务。

3.线程优先级:线程由操作系统调度,给线程指定优先级,就可以影响调度顺序。操作系统根据优先级来调度线程。关于线程调度器的概念??只有优先级相同的多个线程在运行,才用得上时间 量和循环规则。 优先级是动态的。在Thread类中,可以设置Priority属性,以影响线程的基本优先级。Priority属性需要ThreadPriority枚举定义的一个值:Highest,AboveNormal,BelowNormal,Lowest。给线程指定优先级时要小心,因为这可能降低其他线程的运行概率。根据需要,可以短暂地改变优先级。

4.控制线程:读取ThreadState属性可以获得线程的当前状态。在调用Thread的Start()后,新线程仍不是处于Running状态,而是处于Unstarted状态,只要操作系统的线程高度器选择了要运行的线程,状态才会改为Running。可用Sleep()方法 ,使线程处于WaitSleepJoin状态。在经历指定的时间段后,线程会等待再次被唤醒。停止线程可用Abort()方法。 调用这个方法时,会 在接到终止命令的 线程中 抛出 一个ThreadAbortException类 型的 异常。 用一个处理程序捕获这个异常,线 程可以 在结束前完成一些 清理工作。 线程还可以 在接收到调用Thread.ResetAbort()方 法的结果 ThreadAbortException异常后继续运行。 如果线程没有重置终止,接 收到终止请求的 线程的 状态就从 AbortRequested改 为Aborted。如果需要等待线程的结束,就 可以 调用Thread.Join()方 法。 会停止当前线程,并把它设置为WaitSleepJoin状 态,直 到加入的线程完成为止。

四、线程池

ThreadPool

线程池使用起来很简单,但 它有一些限 制:
线程池中的所有线程都是后台线程 。如果进程的所有前台线程都结束了,所有的后台线程就会停止。不能把入池的线程改为前台线程 。
不能给入池的线程设置优先级或名称。
对于 COM对 象,入 池的所有线程都是多线程单元(Multithreaded apartment,MTA)线 程。许多 CoM对 象都需要单线程单元(single-threaded apartment ,MTA)线 程。
入池的线程只能用于时间较短的任务。 如果线程要一直运行(如 Word的 拼写检查器线程),就应使用 Thread类 创建一个线程。

五、任务

System.Threading.Tasks,它包含的类抽象出了线程功能,在后台使用ThreadPool。任务表示应完成的某个单元的工作 。这个单元的工作可以在单独的线程中运行,也可以以同步方式启动一个任务,这需要等待主调线程。使用任务不仅可以获得一个抽象层,还可以对底层线程进行很多控制。在安排需要完成的工作时,任务提供了大的灵活性。

相关类或方法 :TaskFactory类或Task类的构造函数和Start()方法 。

在启 动任务时,会创建Task类 的 一 个实 例,利 用Action或Action<object>委托(不带 参数或带一个object参数) ,可 以 指定 应 运行的 代码。

~~~~~~~~~~~~~~有新任务了,先暂停吧,工作要紧~~

有任务了,证明我还是有价值的,我还是值得留下 的,我的工作暂时还是稳定的,呃。。。好好干吧~~

原文地址:https://www.cnblogs.com/gdx4430090/p/3180381.html