मेल क्लाइंट्स में मल्टी-थ्रेडिंग समर्थन
ImapClient और Pop3Client जैसे मेल क्लाइंट उपयोगकर्ताओं को मल्टी‑थ्रेडिंग वातावरण में उनका उपयोग करने की अनुमति देते हैं। मेल क्लाइंट एक या अधिक सर्वर कनेक्शन रख सकते हैं। क्लाइंट के भीतर कनेक्शन सेट को प्रबंधित करने के लिए कनेक्शन पूल का उपयोग किया जाता है। एक साथ बनाए और उपयोग किए जा सकने वाले कनेक्शन की संख्या 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 इंटरफ़ेस को लागू करता है। कनेक्शन को रिलीज़ करने के लिए Dispose मेथड को बुलाना आवश्यक है। कनेक्शन का निर्माण और डिस्पोज़ करना वही थ्रेड के भीतर किया जाना चाहिए जहाँ मेल ऑपरेशन्स चलाते हैं। उस थ्रेड में नई कनेक्शन बनाने का प्रयास जहाँ मेल क्लाइंट बनाया गया है, त्रुटि उत्पन्न करता है, क्योंकि इस क्षण वह थ्रेड नई कनेक्शन निर्माण के लिए उपयोग नहीं किया जा सकता। साथ ही जब MaxConnectionsPerServer = 1 हो तो नई कनेक्शन बनाना संभव नहीं है। अतिरिक्त थ्रेड में नई कनेक्शन बनाने का कोड उदाहरण:
सिफारिशें
ध्यान देने योग्य बात यह है कि यदि उपयोगकर्ता सभी कमांड मुख्य कनेक्शन को भेजता है, तो विभिन्न थ्रेडों से आने वाले कमांड मिश्रित हो सकते हैं। उपयोगकर्ता को समझना चाहिए कि कौन से कमांड उनकी क्रमबद्धता पर निर्भर हैं, और ऐसे कमांडों के सिंक्रनाइज़ेशन के उपाय करने चाहिए। यह भी आवश्यक है कि विभिन्न सत्रों (IMAP/POP3) में कमांडों को निष्पादित करने की संभावना पर विचार किया जाए। सबसे अधिक समय लेनी वाली ऑपरेशन्स, जैसे FetchMessage, AppendMessage और Send, संभवतः नए थ्रेड और नई कनेक्शन के साथ करने का उपयुक्त होगा। लेकिन Delete जैसी त्वरित ऑपरेशन्स को मुख्य कनेक्शन के साथ करना उचित है। कृपया ध्यान दें कि नई कनेक्शन का प्रारम्भिककरण स्वयं ही पर्याप्त समय लेने वाला ऑपरेशन है।