सुझाव कमजोर संदर्भ दौड़ का समाधान नहीं करता से बचने के लिए:
(वहाँ गणना की जाती है (मजबूत) संदर्भ, और बस इतना ही इसके अलावा, ध्यान दें कि COM वास्तव में कमजोर संदर्भ के साथ शुरू करने के लिए की एक अवधारणा नहीं है।) मुद्दा।
T1 operator new, create object, references: 1
T1 passes interface object reference to T2, thinking it can "share" ownership
T1 suspends
T2 resumes
T2 QueryInterface
T2 suspends before InterlockedIncrement, references: 1
T1 resumes
T1 Calls Release
T1 suspends between InterlockedDecrement and operator delete, references: 0
T2 resumes, InterlockedIncrement occurs, references 1
T2 suspends
T1 resumes, operator delete executes, references 1 !!!
T1 suspends
T2 resumes
T2 Any reference to the interface is now invalid since it has been deleted with reference count 1.
यह COM सर्वर में हल करने योग्य है। हालांकि, COM क्लाइंट को इस दौड़ की स्थिति को रोकने वाले सर्वर पर निर्भर नहीं होना चाहिए। इसलिए, COM क्लाइंट को थ्रेड के बीच इंटरफ़ेस ऑब्जेक्ट्स साझा नहीं करना चाहिए। इंटरफ़ेस ऑब्जेक्ट तक पहुंचने की अनुमति देने वाला एकमात्र धागा, एक थ्रेड है जो वर्तमान में इंटरफ़ेस ऑब्जेक्ट का "मालिक" है।
टी 1 को रिलीज नहीं कहा जाना चाहिए था। हां, यह इंटरफ़ेस ऑब्जेक्ट को T2 पर पास करने से पहले AddRef कहा जा सकता था। लेकिन वह दौड़ को हल नहीं कर सकता है, केवल इसे किसी और जगह ले जाएं। सबसे अच्छा अभ्यास हमेशा एक-इंटरफ़ेस-ऑब्जेक्ट, एक-स्वामी की अवधारणा को बनाए रखना है।
COM सर्वर अवधारणा दो (या अधिक) इंटरफेस कुछ साझा सर्वर-आंतरिक स्थिति संदर्भित कर सकते हैं कि समर्थन करने के लिए चाहता है, COM सर्वर एक CreateCopyOfInstance विधि की आपूर्ति करके अनुबंध का विज्ञापन और विवाद का प्रबंधन, आंतरिक रूप से करना चाहिए। निश्चित रूप से, सर्वर के उदाहरण हैं जो इस तरह के "प्रशंसक-आउट" को संभालते हैं। माइक्रोसॉफ्ट से लगातार स्टोरेज इंटरफेस पर एक नज़र डालें। वहां, इंटरफेस "फैन-आउट" नहीं होते हैं .. प्रत्येक इंटरफ़ेस का स्वामित्व एक उपयोगकर्ता (थ्रेड/प्रोसेस/जो भी हो) के स्वामित्व में होना चाहिए और "प्रशंसक-आउट" को सर्वर द्वारा आंतरिक रूप से प्रबंधित किया जाता है, जिसमें विधियों को प्रदान किया जाता है COM क्लाइंट विवाद मुद्दों के कुछ पहलुओं को नियंत्रित करने के लिए। इसलिए, माइक्रोसॉफ्ट के COM सर्वर को अपने ग्राहकों के लिए अपने अनुबंधों के हिस्से के रूप में दौड़ की स्थिति को संबोधित करना होगा।
आह ... तो यह थ्रेडिंग के कारण है, मुझे इसका एहसास नहीं हुआ। धन्यवाद! +1 – Mehrdad
यहां तक कि थ्रेडिंग भी नहीं, अगर आप * कमजोर * से पहले अपने * मजबूत * (इसे इसे कॉल करें) संदर्भ 'रिलीज़ करें' तो एक * कमजोर * संदर्भ अब वैध नहीं है। कॉलिंग 'रिलीज' मूल रूप से कहने का आपका तरीका है "ठीक है मैं कर चुका हूं" - एक बार जब आप इसे कॉल करते हैं, तो ऑब्जेक्ट का उपयोग करना बंद करें। यदि आपको ऑब्जेक्ट का उपयोग करना जारी रखना है ... 'रिलीज' को कॉल न करें। –
दाएं; मैं केवल उस मामले के बारे में सोच रहा था जहां आप 'इंटरफेस' को 'इंटरफ़ेस' पर कॉल करते हैं * तुरंत 'आपकी' क्वेरी इंटरफेस 'कॉल के बाद, और इसलिए मैंने दौड़ की स्थिति के बारे में नहीं सोचा था। – Mehrdad