เธรดถูกกำหนดให้เป็นเส้นทางการดำเนินการของโปรแกรม แต่ละเธรดจะกำหนดการควบคุมการไหลที่ไม่ซ้ำกัน หากแอปพลิเคชันของคุณเกี่ยวข้องกับการดำเนินการที่ซับซ้อนและใช้เวลานาน เช่น การเข้าถึงฐานข้อมูลหรือการดำเนินการ I/O ที่เข้มข้น มักจะเป็นประโยชน์อย่างมากในการตั้งค่าพาธการดำเนินการหรือเธรดที่แตกต่างกัน โดยแต่ละเธรดจะทำงานเฉพาะเจาะจง
เธรดเป็นกระบวนการที่มีน้ำหนักเบา ตัวอย่างทั่วไปของการใช้เธรดคือการใช้งานการเขียนโปรแกรมแบบขนานในระบบปฏิบัติการสมัยใหม่ การใช้เธรดจะช่วยลดการสูญเสียวงจรของ CPU และปรับปรุงประสิทธิภาพของแอปพลิเคชัน
โปรแกรมที่เรารวบรวมจนถึงตอนนี้ทำงานเป็นกระบวนการเดียวบนเธรด ซึ่งเป็นอินสแตนซ์ที่รันอยู่ของแอปพลิเคชัน อย่างไรก็ตาม แอปพลิเคชันดังกล่าวสามารถทำงานได้ครั้งละหนึ่งงานเท่านั้น หากต้องการให้แอปทำงานหลายอย่างพร้อมกัน คุณสามารถแบ่งออกเป็นเธรดเล็กๆ ได้
ใน .Net เธรดจะถูกจัดการผ่านเนมสเปซ 'System.Threading' การสร้างตัวแปรประเภท system.threading.thread ช่วยให้คุณสร้างเธรดใหม่เพื่อเริ่มทำงานได้ อนุญาตให้คุณสร้างและเข้าถึงเธรดอิสระในเธรดแยกต่างหาก
เธรดถูกสร้างขึ้นจากวัตถุเธรด และตัวสร้างของเธรดจะได้รับการอ้างอิงถึงการเริ่มต้นเธรด
ThreadStart childthreat = ThreadStart ใหม่ (childthreadcall);
วงจรชีวิตของเธรดเริ่มต้นเมื่ออ็อบเจ็กต์ของคลาส system.threading.thread ถูกสร้างขึ้น และสิ้นสุดเมื่อเธรดถูกยกเลิกหรือการดำเนินการเสร็จสิ้น
ต่อไปนี้คือสถานะต่างๆ ในวงจรชีวิตของเธรด:
สถานะเริ่มต้นที่รอดำเนินการ: มีการสร้างอินสแตนซ์ของเธรดแล้ว แต่ยังไม่ได้เรียกวิธีการเริ่มต้นระบบ
สถานะพร้อม: สถานการณ์เมื่อเธรดพร้อมที่จะดำเนินการและรอรอบการทำงานของ CPU
สถานะไม่รัน: เมื่อเธรดไม่สามารถทำงานได้ มีความเป็นไปได้หลายประการ:
วิธีการนอนหลับปัจจุบันเรียกว่า
เรียกว่าวิธีการรอ
ถูกบล็อกโดยการดำเนินการ I/O
สถานะการตาย: เธรดได้เสร็จสิ้นการดำเนินการหรือถูกยกเลิก
คุณลักษณะลำดับความสำคัญในคลาส Thread ส่วนใหญ่จะระบุลำดับความสำคัญของเธรดที่สัมพันธ์กับเธรดอื่น รันไทม์ .NET จะเลือกเธรดที่พร้อมใช้งานซึ่งมีลำดับความสำคัญสูงสุด ลำดับความสำคัญสามารถแบ่งออกเป็น:
สูงกว่าปกติ
ต่ำกว่าปกติ
สูงสุด
ต่ำสุด
ปกติ
เมื่อเธรดถูกสร้างขึ้น ระบบจะกำหนดลำดับความสำคัญโดยใช้ระบบการตั้งค่าลำดับความสำคัญของคลาสเธรด
NewThread.Priority = ThreadPriority.Highest;
คลาสเธรดมีคุณสมบัติที่สำคัญดังต่อไปนี้:
คุณสมบัติ | อธิบาย |
---|---|
บริบทปัจจุบัน | รับเนื้อหาของเธรดที่กำลังดำเนินการอยู่ |
ปัจจุบันวัฒนธรรม | รับหรือตั้งค่าสภาพแวดล้อมของเธรดปัจจุบัน |
หลักการปัจจุบัน | รับหรือตั้งค่านโยบายความปลอดภัยตามบทบาทของกระบวนการปัจจุบัน |
เธรดปัจจุบัน | รับเธรดที่กำลังทำงานอยู่ |
ปัจจุบัน UICulture | รับหรือตั้งค่าสภาพแวดล้อมปัจจุบันที่ใช้โดยผู้จัดการทรัพยากรของกระบวนการที่กำลังทำงานอยู่เพื่อค้นหาทรัพยากรเฉพาะ |
บริบทการดำเนินการ | รับวัตถุ ExecutionContext ที่ประกอบด้วยข้อมูลเชิงบริบทเกี่ยวกับเธรดปัจจุบัน |
ยังมีชีวิตอยู่ | รับค่าที่ระบุสถานะการดำเนินการของเธรดปัจจุบัน |
เป็นพื้นหลัง | พื้นหลังรับหรือตั้งค่าที่ระบุว่าเธรดนั้นเป็นเธรดพื้นหลังหรือไม่ |
IsThreadPoolThread | รับค่าที่ระบุว่าเธรดเป็นของพูลเธรดที่ได้รับการจัดการหรือไม่ |
ManagedThreadId | รับตัวระบุเฉพาะปัจจุบันของเธรดที่ได้รับการจัดการ |
ชื่อ | รับหรือตั้งชื่อเธรด |
ลำดับความสำคัญ | รับหรือตั้งค่าที่ระบุลำดับความสำคัญของกำหนดการของเธรด |
สถานะเธรด | รับค่าที่มีสถานะของเธรดปัจจุบัน |
คลาสเธรดมีวิธีการที่สำคัญดังต่อไปนี้:
วิธี | อธิบาย |
---|---|
ยกเลิก | การเรียก ThreadAbortException จะเริ่มต้นกระบวนการยุติเธรด การเรียกวิธีนี้มักจะยุติเธรด |
จัดสรร DataSlot | เธรดทั้งหมดถูกกำหนดช่องข้อมูลที่ไม่มีชื่อ เพื่อประสิทธิภาพที่ดีขึ้น ให้ใช้ฟิลด์ที่มีเครื่องหมายแอตทริบิวต์ ThreadStaticAttribute |
AllocateNamedDataSlot | จัดสรรช่องข้อมูลที่มีชื่อให้กับเธรดทั้งหมด เพื่อประสิทธิภาพที่ดีขึ้น ให้ใช้ฟิลด์ที่มีเครื่องหมายแอตทริบิวต์ ThreadStaticAttribute |
เริ่มต้นภูมิภาควิกฤติ | แจ้งโฮสต์ว่าการดำเนินการกำลังจะเข้าสู่ขอบเขตโค้ดซึ่งผลกระทบของเธรดถูกยกเลิกหรือข้อยกเว้นที่ไม่สามารถจัดการได้อาจทำให้งานอื่นเสียหายได้ |
เริ่มต้น ThreadAffinity | แจ้งโฮสต์ว่าโค้ดที่ได้รับการจัดการกำลังจะดำเนินการ ขึ้นอยู่กับข้อมูลประจำตัวของเธรดระบบปฏิบัติการจริงปัจจุบัน |
EndCriticalRegion | แจ้งโฮสต์ว่าการดำเนินการกำลังจะเข้าสู่ขอบเขตของโค้ดที่เธรดถูกยกเลิกหรือมีข้อยกเว้นที่ไม่สามารถจัดการได้จะส่งผลต่องานปัจจุบันเท่านั้น |
EndThreadAffinity | แจ้งให้โฮสต์ทราบว่าการเรียกใช้โค้ดที่ได้รับการจัดการเสร็จสมบูรณ์แล้ว ขึ้นอยู่กับข้อมูลเฉพาะตัวของเธรดระบบปฏิบัติการจริงในปัจจุบัน |
ฟรี NamedDataSlot | ขจัดการเชื่อมโยงระหว่างชื่อและสล็อตสำหรับเธรดทั้งหมดในกระบวนการ เพื่อประสิทธิภาพที่ดีขึ้น ให้ใช้ฟิลด์ที่มีเครื่องหมายแอตทริบิวต์ ThreadStaticAttribute |
รับข้อมูล | ดึงค่าจากช่องที่ระบุโดยเธรดปัจจุบันในโดเมนปัจจุบันของเธรดปัจจุบัน เพื่อประสิทธิภาพที่ดีขึ้น ให้ใช้ฟิลด์ที่มีเครื่องหมายแอตทริบิวต์ ThreadStaticAttribute |
รับโดเมน | ส่งกลับเธรดที่กำลังดำเนินการอยู่ในโดเมนปัจจุบัน |
รับDomainID | ส่งกลับตัวระบุโดเมนแอปพลิเคชันเฉพาะ |
GetNamedDataSlot | ค้นหาช่องข้อมูลที่มีชื่อ เพื่อประสิทธิภาพที่ดีขึ้น ให้ใช้ฟิลด์ที่มีเครื่องหมายแอตทริบิวต์ ThreadStaticAttribute |
ขัดจังหวะ | ขัดจังหวะเธรดในสถานะเธรด WaitSleepJoin |
เข้าร่วม | บล็อกเธรดที่เรียกจนกว่าเธรดใดเธรดหนึ่งจะยุติลง ในขณะที่ดำเนินการ COM และ SendMessage มาตรฐานต่อไป วิธีนี้มีรูปแบบการโอเวอร์โหลดที่แตกต่างกัน |
อุปสรรคแห่งความทรงจำ | การเข้าถึงหน่วยความจำแบบซิงโครนัสมีดังนี้: ตัวเร่งความเร็วที่ประมวลผลเธรดปัจจุบันไม่สามารถเรียงลำดับคำสั่งใหม่ในลักษณะที่การเข้าถึงหน่วยความจำเรียก MemoryBarrier ตามด้วยการดำเนินการเข้าถึงหน่วยความจำ |
รีเซ็ตยกเลิก | ยกเลิกคำขอยกเลิกของเธรดปัจจุบัน |
ตั้งค่าข้อมูล | ตั้งค่าข้อมูลสำหรับเธรดที่กำลังรันอยู่ในช่วงเวลาที่ระบุ และโดเมนปัจจุบันของเธรดนั้น เพื่อประสิทธิภาพที่ดีขึ้น โดเมนแอปพลิเคชันมีแอตทริบิวต์ ThreadStaticAttribute ของโดเมน |
เริ่ม | เริ่มกระทู้ |
นอน | ทำให้เธรดหยุดชั่วคราวเป็นระยะเวลาหนึ่ง |
สปินรอท | ทำให้เธรดรอตามจำนวนการวนซ้ำที่กำหนดโดยพารามิเตอร์ |
อ่านระเหย() | อ่านค่าของสนาม ค่าล่าสุดถูกเขียนโดยโปรเซสเซอร์ใดๆ ของคอมพิวเตอร์ โดยไม่คำนึงถึงหมายเลขสถานะแคชของโปรเซสเซอร์หรือโปรเซสเซอร์ วิธีนี้มีรูปแบบการโอเวอร์โหลดที่แตกต่างกัน |
ระเหยเขียน() | เขียนค่าลงในฟิลด์ที่โปรเซสเซอร์ทั้งหมดในคอมพิวเตอร์มองเห็นได้ทันที วิธีนี้มีรูปแบบการโอเวอร์โหลดที่แตกต่างกัน |
ผลผลิต | ทำให้เธรดที่เรียกดำเนินการเธรดอื่นที่สามารถทำงานบนตัวประมวลผลปัจจุบัน และระบบปฏิบัติการเลือกที่จะเปลี่ยนเส้นทางเธรด |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้คลาสเธรด เพจนี้มีป้ายกำกับควบคุมที่แสดงข้อความจากเธรดย่อย ข้อความจากโปรแกรมหลักจะแสดงโดยตรงโดยใช้เมธอด response.write(50) ดังนั้นจึงปรากฏที่ด้านบนของหน้า
ไฟล์ต้นฉบับมีดังนี้:
<%@ ภาษาเพจ = "C#" AutoEventWireup = "true" CodeBehind = "Default.aspx.cs" สืบทอด = "threaddemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// TH" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title> หน้าที่ไม่มีชื่อ </title> </head> <body> <form id="form1 " runat="server"> <div> <h3>ตัวอย่างกระทู้</h3> </div> <asp:Label ID="lblmessage" runat="server" Text="Label"> </asp:Label> < /แบบฟอร์ม> </ร่างกาย> </html>
รหัสพื้นหลังเป็นดังนี้:
การใช้ System.Collections การใช้ System.Web.UI ; การใช้ System.Web.UI.WebControls; การใช้ System.Web.UI.WebControls.WebParts; การใช้ System.Xml.Linq; class _Default: System.Web.UI.Page { ได้รับการป้องกันเป็นโมฆะ Page_Load (ผู้ส่งวัตถุ EventArgs e) { ThreadStart childthreat = new ThreadStart (childthreadcall); Response.Write ("Child Thread Started <br/>"); กระทู้(childthreat); child.Start(); Response.Write("Main sleeping for 2 months....<br/>"); Thread.Sleep(2000); Response.Write("<br/>Main aborting child thread<br/>"); child.Abort(); } สาธารณะเป็นโมฆะ childthreadcall() { ลอง{ lblmessage.Text = "<br/ >เธรดย่อยเริ่มต้นแล้ว <br/>"; lblmessage.Text += "เธรดย่อย: เชื่อมโยงถึง 10"; for( int i =0; i<10; i++) { Thread.Sleep(500); lblmessage.Text += "<br/> ในเธรดย่อย </br>"; } lblmessage.Text += "<br/> เธรดย่อยเสร็จแล้ว"; catch(ThreadAbortException e){ lblmessage.Text += "<br /> child thread - ข้อยกเว้น"; }ในที่สุด{ lblmessage.Text += "<br /> เธรดย่อย - ไม่สามารถตรวจจับข้อยกเว้น";
เมื่อเพจถูกโหลด เธรดใหม่จะเริ่มต้นด้วย childthreadcall() เป็นข้อมูลอ้างอิง กิจกรรมของกระทู้หลักจะแสดงบนหน้าเว็บโดยตรง
เธรดที่สองทำงานและส่งข้อความไปยังแท็กควบคุม
เธรดหลักเข้าสู่โหมดสลีป 2000 มิลลิวินาทีในขณะที่เธรดลูกกำลังดำเนินการ
เธรดลูกยังคงทำงานต่อไปจนกว่าจะถูกยกเลิกโดยเธรดหลัก จากนั้นจะส่ง ThreadAbortException และถูกยกเลิก
การควบคุมกลับสู่เธรดหลัก
เมื่อรันโปรแกรมจะส่งข้อมูลดังนี้: