การสนับสนุนหลายเธรดในไคลเอนต์อีเมล
ไคลเอนต์เมลเช่น ImapClient และ Pop3Client อนุญาตให้ผู้ใช้ใช้ในสภาพแวดล้อมหลายเธรด ไคลเอนต์เมลสามารถมีการเชื่อมต่อหนึ่งหรือหลายการเชื่อมต่อกับเซิร์ฟเวอร์ เพื่อจัดการชุดการเชื่อมต่อภายในไคลเอนต์ จะใช้การจัดสระการเชื่อมต่อ (connection pool) จำนวนการเชื่อมต่อที่สามารถสร้างและใช้พร้อมกันได้ถูกจำกัดโดยคุณสมบัติ CredentialsByHostClient.MaxConnectionsPerServer คุณสมบัตินี้อาจตั้งค่าเป็น 1 หรือค่ามากกว่า โดยค่าเริ่มต้นคือ 10 คิวคำสั่งได้ถูกนำมาใช้สำหรับการเชื่อมต่อเพื่อรองรับการทำงานหลายเธรด คำสั่งจะดำเนินการตามขั้นตอนที่ง่ายที่สุดที่กำหนดในโปรโตคอล เช่น Noop, Authenticate เป็นต้น ผู้ใช้สามารถเริ่มดำเนินการคำสั่งจำนวนมากกว่าการเชื่อมต่อที่มีได้ แต่คำสั่งจะทำงานก็ต่อเมื่อไคลเอนต์สามารถสร้างการเชื่อมต่อสำหรับดำเนินการนั้น
วิธีการใช้ไคลเอนต์เมลในสภาพแวดล้อมหลายเธรด
ไคลเอนต์อีเมลมีพฤติกรรมต่อไปนี้:
1. ในกรณีที่ MaxConnectionsPerServer = 1 ไคลเอนต์จะสร้างการเชื่อมต่อ 1 ตัว ทำการยืนยันตัวตนและการให้สิทธิ์ การเชื่อมต่อนี้จะอยู่ในสถานะทำงานจนกว่าไคลเอนต์จะถูกทำลาย การดำเนินการทั้งหมดจากเธรดต่าง ๆ จะถูกส่งไปยังคิวคำสั่งเดียวที่อยู่ในการเชื่อมต่อหลัก
2. ในกรณีที่ MaxConnectionsPerServer > 1 ไคลเอนต์จะสร้างจำนวนการเชื่อมต่อที่ต้องการ ทำการยืนยันตัวตนและการให้สิทธิ์สำหรับแต่ละการเชื่อมต่อ การเชื่อมต่อหนึ่งจะถูกสงวนเป็นการเชื่อมต่อหลัก การเชื่อมต่อนี้จะคงอยู่ในสถานะทำงานจนกว่าไคลเอนต์จะถูกทำลาย การเชื่อมต่ออื่น ๆ จะถูกสร้างและทำลายตามความต้องการ จำนวนสูงสุดของการเชื่อมต่อเช่นนี้กำหนดโดยคุณสมบัติ MaxConnectionsPerServer กล่าวคือ หาก MaxConnectionsPerServer = 2 จะมีหนึ่งการเชื่อมต่อสงวนเป็นหลักและการเชื่อมต่อที่สองใช้เป็นเพิ่มเติมสำหรับการดำเนินการที่ทำในเธรดอื่น ๆ ตามลำดับ หาก MaxConnectionsPerServer = 3 จะมีการเชื่อมต่อแรกสงวนเป็นหลักและสองการเชื่อมต่ออื่นใช้เป็นเพิ่มเติมสำหรับการดำเนินการในเธรดอื่น หากมีคำขอการเชื่อมต่อจากเธรดใหม่และการเชื่อมต่อทั้งหมดถูกใช้ ไคลเอนต์จะรอจนจำนวนการเชื่อมต่อที่ใช้ลดลง นี่เป็นจุดสำคัญที่ทำให้เข้าใจว่าการทำลายการเชื่อมต่ออย่างถูกต้องมีความสำคัญเพียงใด
ตัวอย่าง
ผู้ใช้อาจดำเนินการในเธรดต่าง ๆ ได้หลายวิธี ซึ่งสามารถแบ่งออกเป็นสองประเภท:
1. ผู้ใช้ใช้เมธอดแบบอะซิงโครนัส (Begin/End) ที่กำหนดไว้ในไคลเอนต์ ในกรณีนี้ไคลเอนต์อีเมลจะเปิดเธรดใหม่ตามความต้องการ ในไคลเอ็นต์มีคิวงาน (กรุณาอย่าสับสนกับคิวคำสั่งในการเชื่อมต่อ) งานสามารถดำเนินการได้หากการเชื่อมต่อพร้อมใช้งาน เมื่อจำนวนการเชื่อมต่อที่ใช้ลดลงต่ำกว่าค่าขีดจำกัด ไคลเอ็นต์จะสร้างการเชื่อมต่อใหม่ สร้างเธรดสำหรับงานปัจจุบันและดำเนินการงานนั้น ตัวอย่างการใช้การดำเนินการแบบอะซิงโครนัส:
2. ผู้ใช้สามารถสร้างเธรดโดยใช้วัตถุต่าง ๆ เช่น Thread, ThreadPool, Task หรือวัตถุอื่น ๆ ที่ตั้งใจไว้สำหรับวัตถุประสงค์นี้ นอกจากนี้ผู้ใช้ยังสามารถใช้เธรดที่สร้างในโค้ดของบุคคลที่สาม โดยในระหว่างนี้ไคลเอนต์มีสองรูปแบบของพฤติกรรม
a. หากผู้ใช้ไม่ได้ดำเนินการสร้างการเชื่อมต่อเพิ่มเติมสำหรับการดำเนินการในเธรดนี้ การดำเนินการทั้งหมดสำหรับเธรดนี้จะถูกส่งไปยังคิวคำสั่งของการเชื่อมต่อหลัก ตัวอย่างการดำเนินการในเธรดเพิ่มเติมโดยไม่สร้างการเชื่อมต่อใหม่ ทุกธุรกรรมทำผ่านการเชื่อมต่อหลัก:
b. เมื่อผู้ใช้เรียกใช้เมธอดเพื่อสร้างการเชื่อมต่อใหม่สำหรับเธรดเพิ่มเติม เธรดนั้นจะถูกบล็อกจนกว่าค่าปริมาณโควต้าสำหรับการเชื่อมต่อใหม่จะถูกเปลี่ยนเพื่ออนุญาตการเชื่อมต่อใหม่ จากนั้นการเชื่อมต่อใหม่จะถูกสร้าง การเชื่อมต่อนี้จะถูกตั้งเป็นการเชื่อมต่อเริ่มต้นสำหรับทุกการดำเนินการในเธรดนี้ หลังจากที่การดำเนินการทั้งหมดในเธรดนี้เสร็จสิ้น การเชื่อมต่อต้องถูกทำลาย เพื่อสร้างการเชื่อมต่อใหม่ใช้เมธอด CredentialsByHostClient.CreateConnection เมธอดนี้จะคืนค่าอ็อบเจกต์ที่ 구현 IDisposable interface เพื่อปล่อยการเชื่อมต่อต้องเรียก Dispose การสร้างและการทำลายการเชื่อมต่อต้องดำเนินการภายในเธรดที่ทำการดำเนินการเมล หากพยายามสร้างการเชื่อมต่อใหม่ในเธรดที่สร้างไคลเอนต์เมล จะเกิดข้อผิดพลาด เนื่องจากเธรดนั้นในขณะนั้นไม่สามารถใช้สร้างการเชื่อมต่อใหม่ได้ นอกจากนี้การสร้างการเชื่อมต่อใหม่ไม่เป็นไปได้เมื่อ MaxConnectionsPerServer = 1 ตัวอย่างโค้ดการสร้างการเชื่อมต่อใหม่ในเธรดเพิ่มเติม:
คำแนะนำ
ควรสังเกตว่าหากผู้ใช้ส่งคำสั่งทั้งหมดไปยังการเชื่อมต่อหลัก อาจเกิดสถานการณ์ที่คำสั่งจากเธรดต่าง ๆ ปะปนกัน ผู้ใช้ควรเข้าใจว่าคำสั่งใดพึ่งพาลำดับของมันและต้องดำเนินการเพื่อซิงโครไนซ์คำสั่งเหล่านั้น นอกจากนี้ยังต้องพิจารณาความเป็นไปได้ของการดำเนินคำสั่งในเซสชันต่าง ๆ (IMAP/POP3) งานที่ใช้เวลามากที่สุด เช่น FetchMessage, AppendMessage และ Send อาจเหมาะกับการทำในเธรดใหม่และการเชื่อมต่อใหม่ แต่งานที่เร็วเช่น Delete ควรทำกับการเชื่อมต่อหลัก โปรดทราบว่าการเริ่มต้นการเชื่อมต่อใหม่เป็นงานที่กินเวลามากพอสมควร