คุณช่วยอธิบาย STA และ MTA ด้วยคำพูดของคุณเองได้ไหม?
นอกจากนี้สิ่งที่เป็นหัวข้อพาร์ทเมนต์และพวกเขาเกี่ยวข้องกับ COM เท่านั้น? ถ้าเป็นเช่นนั้นทำไม
คุณช่วยอธิบาย STA และ MTA ด้วยคำพูดของคุณเองได้ไหม?
นอกจากนี้สิ่งที่เป็นหัวข้อพาร์ทเมนต์และพวกเขาเกี่ยวข้องกับ COM เท่านั้น? ถ้าเป็นเช่นนั้นทำไม
คำตอบ:
รูปแบบการเธรด COM เรียกว่าแบบจำลอง "อพาร์ทเมนท์" ซึ่งบริบทการดำเนินการของวัตถุ COM ที่เริ่มต้นถูกเชื่อมโยงกับเธรดเดี่ยว (Single Thread Apartment) หรือเธรดจำนวนมาก (Multi Thread Apartment) ในรุ่นนี้วัตถุ COM ที่เริ่มต้นครั้งแรกในอพาร์ทเมนต์เป็นส่วนหนึ่งของอพาร์ทเมนต์นั้นในช่วงระยะเวลาของการใช้งานจริง
รุ่น STA ใช้สำหรับวัตถุ COM ที่ไม่ปลอดภัยเธรด นั่นหมายความว่าพวกเขาไม่จัดการการซิงโครไนซ์ของตนเอง การใช้งานทั่วไปนี้เป็นองค์ประกอบ UI ดังนั้นหากเธรดอื่นต้องการโต้ตอบกับวัตถุ (เช่นการกดปุ่มในรูปแบบ) ดังนั้นข้อความจะถูกจัดเรียงบนเธรด STA หน้าต่างฟอร์มระบบปั๊มข้อความเป็นตัวอย่างของสิ่งนี้
ถ้าวัตถุ COM สามารถจัดการกับการซิงโครไนซ์ของตัวเองแล้วรุ่น MTA สามารถใช้ที่อนุญาตให้มีหลายเธรดเพื่อโต้ตอบกับวัตถุโดยไม่เรียก marshalled
ทุกอย่างลงไปถึงวิธีการจัดการการโทรไปยังวัตถุและการป้องกันที่จำเป็น วัตถุ COM สามารถถามรันไทม์เพื่อป้องกันไม่ให้ถูกเรียกโดยหลายเธรดในเวลาเดียวกัน สิ่งที่ไม่สามารถเรียกได้พร้อมกันจากเธรดที่แตกต่างกันดังนั้นพวกเขาจึงต้องปกป้องข้อมูลของตัวเอง
นอกจากนี้ยังจำเป็นสำหรับรันไทม์เพื่อป้องกันการโทรวัตถุ COM ไม่ให้บล็อกส่วนต่อประสานผู้ใช้หากมีการโทรจากเธรดส่วนต่อประสานผู้ใช้
พาร์ทเมนท์เป็นสถานที่สำหรับวัตถุที่จะมีชีวิตอยู่และพวกเขามีมากกว่าหนึ่งหัวข้อ อพาร์ตเมนต์กำหนดสิ่งที่เกิดขึ้นเมื่อมีการโทรออก การโทรไปยังวัตถุในอพาร์ทเมนต์นั้นจะได้รับและประมวลผลบนเธรดใด ๆ ในอพาร์ทเมนต์นั้นยกเว้นว่าการโทรโดยเธรดที่อยู่ในอพาร์ทเมนต์นั้นจะถูกดำเนินการด้วยตัวเอง (เช่นการโทรโดยตรงไปยังวัตถุ)
เธรดสามารถอยู่ในอพาร์ทเมนต์แบบเธรดเดียว (ซึ่งในกรณีนี้เป็นเธรดเดียวในอพาร์ทเมนต์นั้น) หรือในอพาร์ตเมนต์แบบมัลติเธรด พวกเขาระบุว่าเมื่อใดที่เธรดเริ่มต้น COM สำหรับเธรดนั้น
STA นั้นเข้ากันได้กับอินเทอร์เฟซผู้ใช้เป็นหลักซึ่งเชื่อมโยงกับเธรดเฉพาะ STA รับการแจ้งเตือนการโทรเพื่อดำเนินการโดยรับข้อความหน้าต่างไปยังหน้าต่างที่ซ่อนอยู่ เมื่อทำการโทรออกจะเริ่มการวนรอบข้อความที่เป็นโมฆะเพื่อป้องกันไม่ให้มีการประมวลผลข้อความหน้าต่างอื่น ๆ คุณสามารถระบุตัวกรองข้อความที่จะเรียกใช้เพื่อให้แอปพลิเคชันของคุณสามารถตอบกลับข้อความอื่น ๆ ได้
ในทางตรงกันข้ามเธรด MTA ทั้งหมดแบ่งปัน MTA เดียวสำหรับกระบวนการ COM อาจเริ่มเธรดของผู้ปฏิบัติงานใหม่เพื่อจัดการการโทรเข้าหากไม่มีเธรดพร้อมใช้งานจนถึงขีด จำกัด ของพูล หัวข้อการโทรออกเพียงแค่บล็อก
เพื่อความง่ายเราจะพิจารณาเฉพาะอ็อบเจกต์ที่นำไปใช้ใน DLLs ซึ่งโฆษณาในรีจิสตรีที่สนับสนุนด้วยการตั้งThreadingModel
ค่าสำหรับคีย์ของคลาส มีสี่ตัวเลือก:
ThreadingModel
ไม่มีค่า) วัตถุถูกสร้างขึ้นบนเธรด UI หลักของโฮสต์และการโทรทั้งหมดจะถูกจัดเรียงในเธรดนั้น โรงงานคลาสจะถูกเรียกบนเธรดนั้นเท่านั้นApartment
. สิ่งนี้บ่งชี้ว่าคลาสสามารถรันบนเธรดโหมดเธรดเดี่ยวใด ๆ หากเธรดที่สร้างขึ้นเป็นเธรด STA วัตถุจะทำงานบนเธรดนั้นมิฉะนั้นจะถูกสร้างขึ้นใน STA หลัก - หากไม่มี STA หลักอยู่เธรด STA จะถูกสร้างขึ้น (ซึ่งหมายความว่าเธรด MTA ที่สร้างอพาร์ทเมนต์วัตถุจะเป็น marshalling การเรียกทั้งหมดไปยังเธรดอื่น) โรงงานคลาสสามารถถูกเรียกพร้อมกันโดยเธรด STA หลายเธรดดังนั้นจึงต้องป้องกันข้อมูลภายในจากสิ่งนี้Free
. สิ่งนี้บ่งชี้คลาสที่ออกแบบมาให้ทำงานใน MTA มันจะโหลดใน MTA เสมอแม้ว่าจะสร้างโดยเธรด STA ซึ่งหมายความว่าการเรียกเธรด STA จะถูกจัดเรียงใหม่อีกครั้ง นี่เป็นเพราะFree
วัตถุถูกเขียนโดยทั่วไปด้วยความคาดหวังว่ามันสามารถปิดกั้นBoth
. คลาสเหล่านี้มีความยืดหยุ่นและโหลดในอพาร์ตเมนต์ที่สร้างขึ้น พวกเขาจะต้องเขียนให้เหมาะสมกับข้อกำหนดทั้งสองชุดอย่างไรก็ตาม: พวกเขาจะต้องปกป้องสถานะภายในของพวกเขาจากการโทรพร้อมกันในกรณีที่พวกเขากำลังโหลดใน MTA แต่ต้องไม่บล็อกในกรณีที่พวกเขาโหลดใน STAจาก. NET Framework โดยทั่วไปแล้วใช้[STAThread]
กับเธรดใดก็ได้ที่สร้าง UI เธรดผู้ปฏิบัติงานควรใช้ MTA เว้นแต่ว่าพวกเขากำลังจะใช้Apartment
คอมโพเนนต์ COM ที่มีเครื่องหมายซึ่งในกรณีนี้ใช้ STA เพื่อหลีกเลี่ยงปัญหาค่าใช้จ่ายในการจัดเรียงและการขยายขีดความสามารถหากองค์ประกอบเดียวกันถูกเรียกจากหลายเธรด (เนื่องจากแต่ละเธรด ส่วนประกอบในการเปิด) มันง่ายกว่าถ้าคุณใช้วัตถุ COM แยกกันต่อเธรดไม่ว่าองค์ประกอบนั้นจะอยู่ใน STA หรือ MTA
ฉันพบว่าคำอธิบายที่มีอยู่ gobbledygook เกินไป นี่คือคำอธิบายของฉันในภาษาอังกฤษธรรมดา:
STA: ถ้าเธรดสร้างวัตถุ COM ที่ตั้งค่าเป็น STA (เมื่อเรียก CoCreateXXX คุณสามารถส่งค่าสถานะที่ตั้งค่าวัตถุ COM เป็นโหมด STA) เฉพาะเธรดนี้เท่านั้นที่สามารถเข้าถึงวัตถุ COM นี้ได้ (นั่นคือความหมายของ STA ) เธรดอื่นที่พยายามเรียกใช้เมธอดบนวัตถุ COM นี้อยู่ภายใต้ประทุนกลายเป็นส่งข้อความไปยังเธรดที่สร้าง (เป็นเจ้าของ) วัตถุ COM อย่างเงียบ ๆ นี่เป็นความจริงที่ว่าเฉพาะเธรดที่สร้างตัวควบคุม UI เท่านั้นที่สามารถเข้าถึงได้โดยตรง และกลไกนี้มีไว้เพื่อป้องกันการล็อค / ปลดล็อคที่ซับซ้อน
MTA: ถ้าเธรดสร้างวัตถุ COM ที่ตั้งค่าเป็น MTA แล้วทุก ๆ เธรดสามารถเรียกเมธอดได้โดยตรง
นั่นเป็นส่วนสำคัญของมัน แม้ว่าในทางเทคนิคจะมีรายละเอียดบางอย่างที่ฉันไม่ได้พูดถึงเช่นในย่อหน้า 'STA' แต่ตัวสร้างเธรดต้องเป็น STA แต่นี่คือสิ่งที่คุณต้องรู้เพื่อทำความเข้าใจ STA / MTA / NA
STA (Single Threaded Apartment) นั้นเป็นแนวคิดที่ว่ามีเพียงหนึ่งเธรดที่จะโต้ตอบกับโค้ดของคุณในแต่ละครั้ง การโทรเข้าอพาร์ทเมนต์ของคุณจะถูกจัดการผ่านทางข้อความ windows (โดยใช้หน้าต่างที่มองไม่เห็น) สิ่งนี้อนุญาตให้การโทรถูกจัดคิวและรอการดำเนินการให้เสร็จสมบูรณ์
MTA (Multi Threaded Apartment) เป็นที่ที่หลาย ๆ เธรดสามารถทำงานได้ในเวลาเดียวกันและความรับผิดชอบของคุณในฐานะผู้พัฒนาเพื่อจัดการกับความปลอดภัยของเธรด
มีมากขึ้นที่จะเรียนรู้เกี่ยวกับการทำเกลียวใน COM แต่ถ้าคุณมีปัญหาในการทำความเข้าใจสิ่งที่พวกเขาเป็นแล้วฉันจะบอกว่าการทำความเข้าใจว่า STA คืออะไรและมันทำงานอย่างไรจะเป็นจุดเริ่มต้นที่ดีที่สุดเพราะวัตถุ COM ส่วนใหญ่เป็น STA
Apartment Threads หากเธรดอยู่ในอพาร์ทเมนต์เดียวกันกับออบเจ็กต์ที่ใช้อพาร์ทเมนต์จะเป็นเธรดของอพาร์ทเมนต์ ฉันคิดว่านี่เป็นเพียงแนวคิด COM เพราะเป็นเพียงวิธีการพูดคุยเกี่ยวกับวัตถุและเธรดที่พวกเขาโต้ตอบกับ ...
แต่ละ EXE ที่โฮสต์ตัวควบคุม COM หรือ OLE กำหนดสถานะของอพาร์ทเมนท์ สถานะพาร์ทเมนต์เป็นค่าเริ่มต้น STA (และสำหรับโปรแกรมส่วนใหญ่ควรเป็น STA)
STA - ตัวควบคุม OLE ทั้งหมดตามความจำเป็นต้องอยู่ใน STA STA หมายความว่าวัตถุ COM ของคุณต้องถูกจัดการบนเธรด UI และไม่สามารถส่งผ่านไปยังเธรดอื่น ๆ ได้ (เหมือนกับองค์ประกอบ UI ใด ๆ ใน MFC) อย่างไรก็ตามโปรแกรมของคุณยังสามารถมีหลายเธรด
MTA - คุณสามารถจัดการวัตถุ COM บนเธรดใด ๆ ในโปรแกรมของคุณ
ตามความเข้าใจของฉัน 'อพาร์ทเมนท์' ถูกใช้เพื่อปกป้องวัตถุ COM จากปัญหาหลายเธรด
ถ้าวัตถุ COM ไม่ปลอดภัยเธรดควรประกาศเป็นวัตถุ STA จากนั้นเฉพาะเธรดที่สร้างขึ้นเท่านั้นที่สามารถเข้าถึงได้ เธรดการสร้างควรประกาศว่าตนเองเป็นเธรด STA ภายใต้ประทุนเธรดจะเก็บข้อมูล STA ไว้ใน TLS (Thread Local Storage) เราเรียกพฤติกรรมนี้ว่าเธรดเข้าสู่อพาร์ทเมนต์ STA เมื่อเธรดอื่นต้องการเข้าถึงวัตถุ COM นี้ควรจัดการการเข้าถึงเธรดการสร้าง โดยทั่วไปเธรดการสร้างใช้กลไกข้อความเพื่อประมวลผลการโทรที่ถูกผูกไว้
ถ้าวัตถุ COM เป็นเธรดที่ปลอดภัยมันควรประกาศเป็นวัตถุ MTA วัตถุ MTA สามารถเข้าถึงได้โดยหลายกระทู้
รหัสที่เรียก COM วัตถุ DLLs (ตัวอย่างเช่นการอ่านไฟล์ข้อมูลที่เป็นกรรมสิทธิ์) อาจทำงานได้ดีในส่วนติดต่อผู้ใช้ แต่แขวนอย่างลึกลับจากบริการ เหตุผลก็คือส่วนติดต่อผู้ใช้. Net 2.0 จะถือว่า STA (thread-safe) ในขณะที่บริการถือว่า MTA ((ก่อนหน้านั้นจะถือว่าบริการ STA) การสร้างเธรด STA สำหรับการโทร COM ทุกครั้งในบริการสามารถเพิ่มค่าใช้จ่ายได้อย่างมาก