ข้อความวนซ้ำเป็นโค้ดส่วนเล็ก ๆ ที่มีอยู่ในโปรแกรม Windows ดั้งเดิม มีลักษณะประมาณนี้:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessage () Win32 API ดึงข้อความจาก Windows โดยทั่วไปโปรแกรมของคุณจะใช้เวลา 99.9% อยู่ที่นั่นเพื่อรอให้ Windows แจ้งว่ามีสิ่งที่น่าสนใจเกิดขึ้น TranslateMessage () เป็นฟังก์ชันตัวช่วยที่แปลข้อความบนแป้นพิมพ์ DispatchMessage () ทำให้แน่ใจว่าขั้นตอนหน้าต่างถูกเรียกด้วยข้อความ
ทุกโปรแกรม. NET ที่เปิดใช้งาน GUI จะมีลูปข้อความซึ่งเริ่มต้นโดย Application.Run ()
ความเกี่ยวข้องของการวนรอบข้อความกับ Office เกี่ยวข้องกับ COM โปรแกรม Office เป็นโปรแกรมที่เปิดใช้งาน COM ซึ่งเป็นวิธีการทำงานของคลาส Microsoft.Office.Interop COM ดูแลเธรดในนามของ COM coclass ทำให้มั่นใจได้ว่าการโทรที่ทำบนอินเทอร์เฟซ COM จะทำจากเธรดที่ถูกต้องเสมอ คลาส COM ส่วนใหญ่มีคีย์รีจิสทรีในรีจิสทรีที่ประกาศ ThreadingModel ของตนโดยคลาสทั่วไปส่วนใหญ่ (รวมถึง Office) ใช้ "Apartment" ซึ่งหมายความว่าวิธีเดียวที่ปลอดภัยในการเรียกใช้เมธอดอินเตอร์เฟสคือการโทรจากเธรดเดียวกับที่สร้างคลาสอ็อบเจ็กต์ หรือกล่าวอีกนัยหนึ่ง: โดยคลาส COM ส่วนใหญ่ไม่ปลอดภัยต่อเธรด
ทุกเธรดที่เปิดใช้งาน COM เป็นของอพาร์ตเมนต์ COM มีสองประเภทคือ Single Threaded Apartments (STA) และ Multi Thread Apartment (MTA) ต้องสร้างคลาส COM เธรดของอพาร์ตเมนต์บนเธรด STA คุณสามารถดูสิ่งนี้ได้ในโปรแกรม. NET จุดเริ่มต้นของเธรด UI ของ Windows Forms หรือโปรแกรม WPF มีแอตทริบิวต์ [STAThread] แบบจำลองอพาร์ทเมนต์สำหรับเธรดอื่น ๆ ถูกกำหนดโดยเมธอด Thread.SetApartmentState ()
ระบบประปา Windows ส่วนใหญ่จะทำงานไม่ถูกต้องหากเธรด UI ไม่ใช่ STA โดยเฉพาะอย่างยิ่ง Drag + Drop, คลิปบอร์ด, กล่องโต้ตอบของ Windows เช่น OpenFileDialog, การควบคุมเช่น WebBrowser, แอป UI Automation เช่นโปรแกรมอ่านหน้าจอ และเซิร์ฟเวอร์ COM จำนวนมากเช่น Office
ข้อกำหนดที่ยากสำหรับเธรด STA คือไม่ควรบล็อกและต้องปั๊มวนข้อความ การวนรอบข้อความมีความสำคัญเนื่องจากเป็นสิ่งที่ COM ใช้ในการจัดระเบียบวิธีการเชื่อมต่อจากเธรดหนึ่งไปยังอีกเธรดหนึ่ง แม้ว่า. NET จะทำให้การเรียกมาร์แชลเป็นเรื่องง่าย (เช่น ControlBeginInvoke หรือ Dispatcher BeginInvoke) แต่ก็เป็นเรื่องที่ยุ่งยากมากที่ต้องทำ เธรดที่ดำเนินการเรียกต้องอยู่ในสถานะที่รู้จักกันดี คุณไม่สามารถขัดจังหวะเธรดโดยพลการและบังคับให้เรียกใช้เมธอดได้ซึ่งจะทำให้เกิดปัญหาการกลับเข้ามาใหม่ที่น่ากลัว เธรดควร "ไม่ได้ใช้งาน" ไม่ยุ่งกับการเรียกใช้โค้ดใด ๆ ที่ทำให้สถานะของโปรแกรมกลายพันธุ์
บางทีคุณอาจเห็นว่านำไปสู่ที่ใด: ใช่เมื่อโปรแกรมกำลังดำเนินการวนรอบข้อความแสดงว่าไม่มีการใช้งาน การมาร์แชลจริงเกิดขึ้นผ่านหน้าต่างที่ซ่อนอยู่ซึ่ง COM สร้างขึ้นโดยใช้ PostMessage เพื่อให้มีขั้นตอนหน้าต่างของรหัสรันหน้าต่างนั้น บนเธรด STA วนข้อความช่วยให้มั่นใจว่ารหัสนี้ทำงาน