2012-07-03 11 views
14

सी # में विकास करते समय मैं कई बार इस समस्या में आया हूं। मैं एक खुशी, साथ कोडिंग करने के लिए इधर-उधर धागे और क्या के बीच वस्तुओं गुजर हो जाएगा नहीं है, तो अचानक मैं इस परिचित त्रुटि मिलती है की:कुछ ऑब्जेक्ट्स अलग-अलग धागे से क्यों उपलब्ध नहीं हैं?

"The calling thread cannot access this object because a different thread owns it."

ठीक है, ठीक है, मैं इसके साथ पहले निपटा लिया है, विशेष रूप से जीयूआई धागे पर वस्तुओं के साथ। आपको बस विशिष्ट समस्या के आसपास कार्यक्रम के लिए कुछ अतिरिक्त कोड लिखना होगा। लेकिन हर बार जब मैं किसी ऑब्जेक्ट में आ जाता हूं जो कि सामान्य रूप से सामान्य है, फिर भी इसे विभिन्न धागे से एक्सेस करना पसंद नहीं है।

EDIT मुझे उस ऑब्जेक्ट के बारे में मेरी मूल पोस्ट में गलती हुई थी जो एक्सेस अपवाद पैदा कर रहा था। यह IPAddress, इसके System.Printing.PrintQueue. जो मैं आईपी पता प्राप्त करने के लिए उपयोग कर रहा था। यह वह वस्तु है जिसे आप 1 से अधिक धागे से आकलन नहीं कर सकते हैं।

मेरे द्वारा लिखे गए सभी वर्गों में कभी भी यह समस्या नहीं है। मैं यह भी नहीं जानता कि मैं इसे कैसे कार्यान्वित करूंगा। क्या आपको एक सदस्य चर को थ्रेड आईडी के साथ रखना होगा जो आपको बनाया गया है, और उसके बाद मौजूदा थ्रेड को प्रत्येक संपत्ति और विधि पहुंच के विरुद्ध जांचें? वह पागल लगता है। माइक्रोसॉफ्ट का फैसला क्यों होगा ..... "ठीक है ... प्रिंट क्यूई, निश्चित रूप से धागे के बीच तेज नहीं है। लेकिन इन अन्य वर्गों .... उनके जाने के लिए अच्छा है।"

कुछ ऑब्जेक्ट्स को एकाधिक थ्रेड एक्सेस से अवरुद्ध क्यों किया जाता है?

+2

विकल्प के बारे में सोचें: कोई भी धागा किसी ऑब्जेक्ट को पसंद कर सकता है। अब उस ऑब्जेक्ट को या तो थ्रेडिंग चिंताओं को सही तरीके से संभालने के लिए एक्सेसर पर निर्भर होना है, या यह सुनिश्चित करने के लिए अतिरिक्त कोड का एक गुच्छा लिखना है कि यह एकाधिक धागे से एक्सेसर्स के लिए सुरक्षित है। विकल्प 1 यथार्थवादी नहीं है, और विकल्प 2 बहुत काम है। इसलिए निर्णय 3 के साथ जाने के लिए निर्णय लिया गया था: एकाधिक धागे से एक्सेसर्स को अस्वीकार करें। – dlev

+1

खराब माइक्रोसॉफ्ट। खराब। –

+1

ऐसा लगता है कि सी # कचरा निपटान कुछ चर का उपयोग करता है, इस पर निर्भर करता है कि उनका उपयोग कैसे किया जाता है। मुझे इससे कभी निपटना नहीं था, लेकिन इस समस्या को हल करने और ठीक करने का एक अच्छा तरीका यह है कि यदि आप उन्हें धागे के बीच साझा करने की योजना बनाते हैं तो अपने चर को स्थिर धारक में रखना है। एक थ्रेड अन्य थ्रेड लिखता है। आपको यह सुनिश्चित करने के लिए कुछ लॉकिंग करने की आवश्यकता हो सकती है कि यदि आपके पास मूल्य बदलने की आवश्यकता है तो आपको लिखने पर टकराव नहीं है। –

उत्तर

3

मुझे लगता है कि यह चीजों को काफी अच्छी तरह से समझा सकता है, मुझे लगता है कि यह विशेष रूप से COM के साथ करना है।

http://msdn.microsoft.com/en-us/library/ms693344%28v=vs.85%29

विशेष रूप से

In general, the simplest way to view the COM threading architecture is to think of all the COM objects in the process as divided into groups called apartments. A COM object lives in exactly one apartment, in the sense that its methods can legally be directly called only by a thread that belongs to that apartment. Any other thread that wants to call the object must go through a proxy.

There are two types of apartments: single-threaded apartments, and multithreaded apartments.

Single-threaded apartments consist of exactly one thread, so all COM objects that live in a single-threaded apartment can receive method calls only from the one thread that belongs to that apartment. All method calls to a COM object in a single-threaded apartment are synchronized with the windows message queue for the single-threaded apartment's thread. A process with a single thread of execution is simply a special case of this model.

Multithreaded apartments consist of one or more threads, so all COM objects that live in an multithreaded apartment can receive method calls directly from any of the threads that belong to the multithreaded apartment. Threads in a multithreaded apartment use a model called free-threading. Calls to COM objects in a multithreaded apartment are synchronized by the objects themselves.

+2

तो क्या आप यह कह रहे हैं कि System.Printing.PrintQueue ऑब्जेक्ट वास्तव में एक एसटीए COM ऑब्जेक्ट है, और यही कारण है कि इसे अन्य धागे से छुआ नहीं जा सकता है? System.Printing.PrintQueue प्रलेखन को देखने से, मैं कैसे कह सकता हूं कि यह एक एसटीए COM वस्तु है? – Ultratrunks

+0

दिलचस्प सामान। मुझे लगता है कि यह http://msdn.microsoft.com/en-us/library/5s8ee185.aspx उपरोक्त उत्तर को पूरा करता है (और यह भी बताता है कि क्यों Ultratrunks को जीयूआई प्रोग्रामिंग के साथ संयोजन में ऐसी समस्याएं आईं)। – jpe

+0

@Ultratrunks मैं निश्चित रूप से निश्चित हूं कि क्लास COM wrapper है क्योंकि यह प्रिंट कतार तक पहुंचता है। हालांकि, मुझे नहीं पता कि एसटीए के सामने क्या जानना है। एमएसडीएन में कक्षाओं के लिए एक थ्रेड सुरक्षा अनुभाग है, लेकिन मुझे नहीं देखा कि मुझे वहां क्या देखने की उम्मीद है। –

संबंधित मुद्दे