Asp.net 简明教程
ASP.NET - Multi Threading
线程定义为程序执行路径。每个线程定义一个独特的控制流程。如果您的应用程序包含复杂且耗时的操作,如数据库访问或一些密集 I/O 操作,那么通常通过每个线程执行特定任务来设置不同的执行路径或线程非常有用。
线程是轻量级进程。现代操作系统中实现并发编程的一个常见示例就是线程的使用。使用线程可以节省 CPU 周期并且提高应用程序的效率。
到目前为止,我们编译的程序是其中单个线程作为应用程序的运行实例运行单个进程。但是,通过该方式,应用程序可以一次执行一项任务。为了同时执行多个任务,它可以细分为更小的线程。
在 .Net 中,通过 'System.Threading' 命名空间处理线程。创建 System.Threading.Thread 类型的变量允许您创建一个新线程以开始使用。它允许您在程序中创建和访问各个线程。
Creating Thread
通过创建一个 Thread 对象,为其构造函数提供 ThreadStart 引用来创建线程。
ThreadStart childthreat = new ThreadStart(childthreadcall);
Thread Life Cycle
线程的生命周期从创建System.Threading.Thread类的对象时开始,并在线程终止或完成执行时结束。
以下是线程生命周期中的各个状态:
-
The Unstarted State :这是创建线程实例的情况,但未调用 Start 方法。
-
The Ready State :这是线程准备执行并等待 CPU 周期的状况。
-
The Not Runnable State :当:调用了 Sleep 方法时调用了 Wait 方法时I/O 操作阻塞时线程不可运行
-
The Dead State :这是线程完成执行或已中止的情况。
Thread Priority
Thread 类别的 Priority 属性指定一个线程相对于另一个线程的优先级。.Net 运行时选择具有最高优先级的就绪线程。
优先级可以分为:
-
Above normal
-
Below normal
-
Highest
-
Lowest
-
Normal
一旦创建线程,其优先级使用线程类的 Priority 属性进行设置。
NewThread.Priority = ThreadPriority.Highest;
Thread Properties & Methods
Thread 类具有以下重要属性:
Property |
Description |
CurrentContext |
获取线程正在执行的当前上下问。 |
CurrentCulture |
获取或设置当前线程的语言环境。 |
CurrentPrinciple |
获取或设置角色安全性的线程当前主体。 |
CurrentThread |
获取当前运行的线程。 |
CurrentUICulture |
获取或设置 Resource Manager 使用以在运行时查找特定于区域性的资源的当前区域性。 |
ExecutionContext |
获取包含有关当前线程各种上下文的信息的 ExecutionContext 对象。 |
IsAlive |
获取指示当前线程执行状态的值。 |
IsBackground |
获取或设置指示线程是否是后台线程的值。 |
IsThreadPoolThread |
获取指示线程是否属于托管线程池的值。 |
ManagedThreadId |
获取指示当前托管的线程的唯一标识符。 |
Name |
获取或设置线程的名称。 |
Priority |
获取或设置指示线程调度优先级的值。 |
ThreadState |
获取包含当前线程状态的值。 |
Thread 类有以下重要方法
Methods |
Description |
Abort |
在调用该方法的线程中引发 ThreadAbortException,以开始终止线程的过程。调用此方法通常会终止该线程。 |
AllocateDataSlot |
在所有线程上配置一个未命名的 data slot。为了提升性能,请使用标记了 ThreadStaticAttribute 特性的字段。 |
AllocateNamedDataSlot |
在所有线程上配置一个命名的 data slot。为了提升性能,请使用标记了 ThreadStaticAttribute 特性的字段。 |
BeginCriticalRegion |
通知主机,执行将进入该段代码区域,在这种代码区域中,线程中止或未处理的异常的影响可能危及应用程序域中的其他任务。 |
BeginThreadAffinity |
通知主机,托管代码将执行依赖于当前物理操作系统线程标识的指令。 |
EndCriticalRegion |
通知主机,执行将进入该段代码区域,在这种代码区域中,线程中止或未处理的异常的影响仅限于当前任务。 |
EndThreadAffinity |
通知主机,托管代码已完成执行依赖于当前物理操作系统线程标识的指令。 |
FreeNamedDataSlot |
消除进程中所有线程之间名称与 slot 之间的关联。为了提升性能,请使用标记了 ThreadStaticAttribute 特性的字段。 |
GetData |
在当前线程的当前域中,从当前线程的指定 slot 中检索值。为了提升性能,请使用标记了 ThreadStaticAttribute 特性的字段。 |
GetDomain |
返回当前线程正在运行的当前域。 |
GetDomainID |
返回一个唯一的应用程序域标识符。 |
GetNamedDataSlot |
查找已命名的 data 插槽。为了获得更好的性能,改为使用标记有 ThreadStaticAttribute 特性的字段。 |
Interrupt |
中断处于 WaitSleepJoin 线程状态的线程。 |
Join |
阻塞调用线程,直至一个线程终止,同时继续执行标准的 COM 和 SendMessage pump。此方法有不同的重载形式。 |
MemoryBarrier |
按以下方式同步内存访问:执行当前线程的处理器不能重新排序指令,以便在调用 MemoryBarrier 之前的内存访问在调用 MemoryBarrier 之后的内存访问之后执行。 |
ResetAbort |
取消对当前线程请求的已中止的请求。 |
SetData |
为当前正在运行的线程的当前域设定当前线程指定插槽中的数据。为获得更好的性能,改为使用标记有 ThreadStaticAttribute 特性的字段。 |
Start |
Starts a thread. |
Sleep |
使线程暂停一段 timespan。 |
SpinWait |
使线程等待由 iterations 参数定义的次数。 |
VolatileRead() |
读取字段的值。值是计算机中任何处理器最后写入的值,无论处理器数目或处理器缓存的状态如何。此方法有不同的重载形式。 |
VolatileWrite() |
立即向字段写入一个值,以便计算机中的所有处理器都可见该值。此方法有不同的重载形式。 |
Yield |
使调用线程向在当前处理器上准备好运行的另一个线程提交执行。操作系统选择要提交的线程。 |
Example
以下示例说明了 Thread 类的用途。页面有一个标签控件可用于显示来自子线程的消息。使用 Response.Write() 方法直接显示来自主程序的消息。因此,它们显示在页面的顶部。
源文件如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="threaddemo._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>
Untitled Page
</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>Thread Example</h3>
</div>
<asp:Label ID="lblmessage" runat="server" Text="Label">
</asp:Label>
</form>
</body>
</html>
文件背后的代码如下:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Threading;
namespace threaddemo
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ThreadStart childthreat = new ThreadStart(childthreadcall);
Response.Write("Child Thread Started <br/>");
Thread child = new Thread(childthreat);
child.Start();
Response.Write("Main sleeping for 2 seconds.......<br/>");
Thread.Sleep(2000);
Response.Write("<br/>Main aborting child thread<br/>");
child.Abort();
}
public void childthreadcall()
{
try{
lblmessage.Text = "<br />Child thread started <br/>";
lblmessage.Text += "Child Thread: Coiunting to 10";
for( int i =0; i<10; i++)
{
Thread.Sleep(500);
lblmessage.Text += "<br/> in Child thread </br>";
}
lblmessage.Text += "<br/> child thread finished";
}catch(ThreadAbortException e){
lblmessage.Text += "<br /> child thread - exception";
}finally{
lblmessage.Text += "<br /> child thread - unable to catch the exception";
}
}
}
}