執行緒被定義為程式的執行路徑。 每個執行緒定義一個獨特的控制流程。 如果應用程式涉及複雜和耗時的操作(如資料庫存取或某些緊張的I/O操作),那麼設定不同的執行路徑或執行緒通常會很有幫助,每個執行緒都執行特定的工作。
執行緒是輕量級的過程。 使用執行緒的一個常見例子是由現代作業系統實現並行程式設計。 執行緒的使用節省了CPU週期的浪費並提高了應用程式的效率。
到目前為止,我們編譯的程式中,是以單個執行緒作為應用程式執行的範例來執行。 但是,這樣應用程式一次可以只可執行一項工作。 為了一次執行多個任務,可以將其分成更小的執行緒。
在.Net中,執行緒是通過System.Threading
名稱空間處理的。 建立System.Threading.Thread
型別的變數允許您建立一個新的執行緒開始使用。它允許建立和存取程式中的各個執行緒。
一個執行緒是通過建立一個Thread
類的物件來建立的,給它的構造器一個ThreadStart
參照。
ThreadStart childthreat = new ThreadStart(childthreadcall);
執行緒的生命週期在System.Threading.Thread
類的物件被建立時開始,並線上程被終止或完成執行時結束。
以下是執行緒生命週期中的各種狀態:
Start
方法的情況。Sleep
方法已被呼叫Wait
方法已被呼叫Thread
類的Priority
屬性指定一個執行緒相對於其他執行緒的優先順序。 .Net執行時選擇具有最高優先順序的就緒執行緒。
優先順序可以被分類為:
當執行緒被建立,它的優先順序就使用執行緒類的Priority
屬性來設定。
NewThread.Priority = ThreadPriority.Highest;
Thread
類具有以下重要的屬性:
編號 | 屬性 | 描述 |
---|---|---|
1 | CurrentContext |
獲取執行緒正在執行的當前上下文。 |
2 | CurrentCulture |
獲取或設定當前執行緒的文化。 |
3 | CurrentPrinciple |
獲取或設定執行緒當前的基於角色的安全性的主體。 |
4 | CurrentThread |
獲取當前正在執行的執行緒。 |
5 | CurrentUICulture |
獲取或設定資源管理器在執行時查詢文化特定資源的當前文化。 |
6 | ExecutionContext |
獲取一個ExecutionContext 物件,其中包含有關當前執行緒的各種上下文的資訊。 |
7 | IsAlive |
獲取一個指示當前執行緒執行狀態的值。 |
8 | IsBackground |
獲取或設定一個值,該值指示執行緒是否為後台執行緒。 |
9 | IsThreadPoolThread |
獲取一個值,該值指示執行緒是否屬於託管執行緒池。 |
10 | ManagedThreadId |
獲取當前託管執行緒的唯一識別符號。 |
11 | Name |
獲取或設定執行緒的名稱。 |
12 | Priority |
獲取或設定一個指示執行緒排程優先順序的值。 |
13 | ThreadState |
獲取包含當前執行緒狀態的值。 |
Thread
類具有以下重要的方法:
編號 | 方法 | 描述 |
---|---|---|
1 | Abort |
在呼叫它的執行緒中引發ThreadAbortException 異常,以開始終止執行緒的過程。 呼叫這個方法通常會終止執行緒。 |
2 | AllocateDataSlot |
在所有執行緒上分配一個未命名的資料插槽。為了獲得更好的效能,請使用ThreadStaticAttribute 屬性標記欄位。 |
3 | AllocateNamedDataSlot |
在所有執行緒上分配一個指定的資料插槽。 為了獲得更好的效能,請使用ThreadStaticAttribute 屬性標記欄位。 |
4 | BeginCriticalRegion |
通知主機執行即將進入一個執行緒中止或未處理異常的影響可能危及應用程式域中的其他任務的程式碼區域。 |
5 | BeginThreadAffinity |
通知主機受控代碼即將執行取決於當前物理作業系統執行緒標識的指令。 |
6 | EndCriticalRegion |
通知主機執行即將進入一個執行緒中止或未處理異常的影響被限制在當前任務的程式碼區域。 |
7 | EndThreadAffinity |
通知主機,受控代碼已經完成執行取決於當前物理作業系統執行緒的標識的指令。 |
8 | FreeNamedDataSlot |
消除進程中所有執行緒的名稱和插槽之間的關聯。 為了獲得更好的效能,請使用標記為ThreadStaticAttribute 屬性欄位。 |
9 | GetData |
從當前執行緒的當前域內的當前執行緒的指定插槽中檢索值。 為了獲得更好的效能,請使用標記為ThreadStaticAttribute 屬性欄位。 |
10 | GetDomain |
返回當前執行緒正在執行的當前域。 |
11 | GetDomainID |
返回唯一的應用程式域識別符號。 |
12 | GetNamedDataSlot |
查詢一個命名的資料插槽。 為了獲得更好的效能,請使用ThreadStaticAttribute 屬性標記欄位。 |
13 | Interrupt |
中斷處於WaitSleepJoin 執行緒狀態的執行緒。 |
14 | Join |
阻塞呼叫執行緒,直到執行緒終止,同時繼續執行標準COM和SendMessage 抽取。這種方法有不同的過載形式。 |
15 | MemoryBarrier |
同步記憶體存取,如下所示:執行當前執行緒的處理器不能重新排序指令,以便在呼叫MemoryBarrier 之前執行記憶體存取之後,存取MemoryBarrier 呼叫之後的記憶體存取。 |
16 | ResetAbort |
取消當前執行緒所請求的中止。 |
17 | SetData |
在當前正在執行的執行緒的指定槽中設定該執行緒當前域的資料。為了獲得更好的效能,請使用標記為ThreadStaticAttribute 屬性的欄位。 |
18 | Start |
開始一個執行緒。 |
19 | Sleep |
使執行緒暫停一段時間。 |
20 | SpinWait |
使執行緒等待疊代引數定義的次數。 |
21 | VolatileRead() |
讀取一個欄位的值。該值是計算機中任何處理器寫入的最新值,無論處理器的數量或處理器快取記憶體的狀態如何。這種方法有不同的過載形式。 |
22 | VolatileWrite() |
立即將值寫入欄位,以便計算機中的所有處理器都可以看到該值。 這種方法有不同的過載形式。 |
23 | Yield |
使呼叫執行緒產生執行到另一個準備在當前處理器上執行的執行緒。 作業系統選擇要產生的執行緒。 |
以下範例說明了Thread
類的用法。該頁面具有用於顯示來自子執行緒的訊息的標籤控制元件。 來自主程式的訊息直接使用Response.Write()
方法顯示。 因此,它們出現在頁面的頂部。
首先開啟Visual Studio,建立一個名稱為:MultiThreading 的ASP.Net空網站 專案。並新增一個Web表單檔案 - Default.aspx
原始檔(Default.aspx)如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>ASP.Net多執行緒範例</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>ASP.Net多執行緒範例</h3>
</div>
<asp:Label ID="lblmessage" runat="server" Text="Label">
</asp:Label>
</form>
</body>
</html>
後端程式碼檔案(Default.aspx.cs)如下:
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;
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";
}
}
}
請注意以下幾點
childthreadcall()
方法來啟動一個新執行緒。主執行緒活動直接顯示在網頁上。2000
毫秒,在此期間子執行緒執行。ThreadAbortException
異常並終止。執行專案程式後,得到以下結果 -