C #: क्या होगा यदि एक स्टेटिक मेथड को कई थ्रेड्स से पुकारा जाए?


93

मेरे आवेदन में मेरे पास एक स्थिर विधि है जिसे एक ही समय में कई थ्रेड्स से कहा जाता है। क्या मेरे डेटा के मिश्रित होने का कोई खतरा है?

मेरे पहले प्रयास में विधि स्थिर नहीं थी और मैं कक्षा के कई उदाहरण बना रहा था। उस स्थिति में मेरा डेटा किसी तरह मिल गया। मुझे यकीन नहीं है कि यह कैसे होता है क्योंकि यह केवल कभी-कभी होता है। मैं अभी भी डेब्यू कर रहा हूं। लेकिन अब यह विधि स्थिर है, मुझे अब तक कोई समस्या नहीं है। शायद यह सिर्फ किस्मत है। मुझे यकीन नहीं है।


जवाबों:


96

तरीकों के अंदर घोषित चर (" कैप्चर किए गए " चर के संभावित अपवाद के साथ ) अलग-थलग हैं, इसलिए आपको कोई अंतर्निहित समस्या नहीं मिलेगी; हालाँकि, यदि आपकी स्थैतिक विधि किसी भी साझा स्थिति तक पहुँचती है, तो सभी दांव बंद हो जाते हैं।

साझा-राज्य के उदाहरण होंगे:

  • स्थिर क्षेत्र
  • सामान्य कैश से एक्सेस की गई वस्तुएं (गैर-क्रमांकित)
  • इनपुट मापदंडों के माध्यम से प्राप्त डेटा (और उन वस्तुओं पर राज्य), अगर यह संभव है कि कई थ्रेड्स एक ही वस्तु (एस) को छू रहे हैं

यदि आपने राज्य साझा किया है, तो आपको या तो होना चाहिए:

  • ध्यान रखें कि एक बार साझा किए जाने के बाद राज्य को म्यूट न करें (बेहतर: राज्य का प्रतिनिधित्व करने के लिए अपरिवर्तनीय वस्तुओं का उपयोग करें, और राज्य के स्नैपशॉट को एक स्थानीय चर में ले जाएं - अर्थात whatever.SomeDataबार-बार संदर्भ के बजाय , आप whatever.SomeData एक बार स्थानीय चर में पढ़ते हैं , और फिर बस चर का उपयोग करें - ध्यान दें कि यह केवल अपरिवर्तनीय स्थिति के लिए मदद करता है! "
  • डेटा तक पहुंच को सिंक्रनाइज़ करें (सभी थ्रेड्स को सिंक्रनाइज़ करना होगा) - या तो पारस्परिक रूप से अनन्य या (अधिक दानेदार) रीडर / लेखक

1
@Diego - क्या वह टिप्पणी मेरे लिए, या @ होली के लिए है?
मार्क ग्रेवेल

होली के लिए, बस अपने उत्तर में कुछ व्यावहारिक जानकारी जोड़ने के लिए।
डिएगो परेरा

1
@Marc मैं पूरी तरह से "वेरिएबल्स के अंदर घोषित तरीकों (" कैप्चर किए गए "वैरिएबल के संभावित अपवाद के साथ) अलग-थलग नहीं हो सकता। एक फ़ाइल हैंडल पर विचार करें जो एक स्थिर विधि में घोषित किया गया है। तब एक धागा संभाल का उपयोग कर सकता है जब कोई अन्य धागा इसका उपयोग कर रहा है। यह अप्रत्याशित व्यवहार को जन्म देगा। या आपका "कैप्चर किया गया" वैरिएबल का मतलब "फाइल हैंडल" भी है।
प्रभाकरन

9
@prabhakaran यदि कोई फ़ाइल हैंडल एक मेथड वैरिएबल है, तो यह केवल उस कॉलर पर ही स्कैन किया जाता है । कोई अन्य कॉलर किसी भिन्न चर (विधि चर प्रति-कॉल हैं) से बात कर रहा होगा । अब, अंतर्निहित फ़ाइल तक पहुंच एक अलग मुद्दा है, लेकिन यह c # या .NET से संबंधित नहीं है। यदि हैंडल साझा नहीं किया गया है, तो किसी को म्यूटेक्स / लॉक की उम्मीद होगी यदि यह परिदृश्य संभव है।
मार्क Gravell

28

हां, यह सिर्फ किस्मत है। ;)

इससे कोई फर्क नहीं पड़ता कि विधि स्थिर है या नहीं, डेटा स्थिर है या नहीं, इससे क्या फर्क पड़ता है।

यदि प्रत्येक थ्रेड में डेटा का अपना सेट के साथ कक्षा का अपना अलग उदाहरण है, तो डेटा के मिश्रित होने का कोई जोखिम नहीं है। यदि डेटा स्थिर है, तो डेटा का केवल एक सेट है, और सभी थ्रेड्स एक ही डेटा साझा करते हैं, इसलिए इसमें मिश्रण नहीं करने का कोई तरीका नहीं है।

जब अलग-अलग उदाहरणों में आपका डेटा अभी भी मिलाया जाता है, तो इसकी सबसे अधिक संभावना है क्योंकि डेटा वास्तव में अलग नहीं है।


6
उस लाइन को पसंद किया - It doesn't matter if the method is static or not, what matters is if the data is static or not। बस जोड़ने के लिए, स्थैतिक विधि के दायरे में घोषित स्थानीय चर डेटा का वह हिस्सा नहीं बनाते हैं, जो हमें दिए गए परिदृश्य में परेशान करने की आवश्यकता है।
RBT

बहुत बढ़िया जवाब। काफी मदद की।
फ्रैक्टल

15

कई थ्रेड्स के लिए स्टेटिक तरीके ठीक होने चाहिए।

दूसरी ओर स्थैतिक डेटा एक समस्या पैदा कर सकता है क्योंकि एक ही डेटा को विभिन्न थ्रेड्स से एक्सेस करने के प्रयासों को नियंत्रित करने की आवश्यकता होती है ताकि यह सुनिश्चित हो सके कि एक बार में केवल एक थ्रेड डेटा को पढ़ या लिख ​​रहा है।


2
यहाँ कीवर्ड सिंक्रोनाइज़ेशन :-)
जी स्टोयनेव

2
पढ़ना समवर्ती रूप से होना ठीक है, लेकिन पढ़ना और समवर्ती रूप से लिखना अप्रत्याशित व्यवहार को जन्म देगा
फ्रीस्टाइल

9

MSDN हमेशा कहता है:

किसी भी सार्वजनिक स्थैतिक (विजुअल बेसिक में साझा) इस प्रकार के सदस्य थ्रेड सुरक्षित हैं। किसी भी उदाहरण के सदस्यों को धागा सुरक्षित होने की गारंटी नहीं है।

संपादित करें: जैसा कि यहां के लोग कहते हैं, हमेशा ऐसा नहीं होता है, और स्पष्ट रूप से यह बीसीएल में इस तरह से डिज़ाइन की गई कक्षाओं पर लागू होता है, उपयोगकर्ता द्वारा बनाई गई कक्षाओं में नहीं जहां यह लागू नहीं होता है।


3
ओह! अंत में, मुझे इस नोट का अर्थ समझ में आया जो MSDN प्रलेखन में इतनी बार पाया जाता है। इसलिए मूल रूप से, जब बीसीएल में एमएस एक स्थिर विधि (जहां यह नोट प्रकाशित होता है) को डिजाइन करता है, वे किसी भी चर / सदस्य / राज्य तक नहीं पहुंचते हैं जो उस पद्धति के दायरे से बाहर है। वे पूरी तरह से उस विधि के तर्क को लागू करने के लिए स्थानीय चर को काटे गए तरीके पर निर्भर करते हैं। बहुत खुशी हुई कि आपने साझा किया।
RBT

@ मारकोट, क्या यह सच नहीं है? उदाहरण के सदस्य सुरक्षित हैं क्योंकि एक प्रति उदाहरण है। हालांकि, स्थिर सदस्य सुरक्षित नहीं हैं क्योंकि उन्हें उस वर्ग के सभी उदाहरणों के बीच साझा किया जाता है? quora.com/…
Fractal

1
निर्भर करता है। मैं कभी भी डिफ़ॉल्ट रूप से किसी इंस्टेंट सदस्य का इलाज नहीं करूंगा। यही कारण है कि पुस्तकालयों का एक पूरा सेट और कई अन्य चीजों के बीच डेटा भ्रष्टाचार से बचने के लिए।
मार्कट

1
ठीक है, धन्यवाद @Marcote मैं धीरे-धीरे समझ रहा हूं कि मुझे बहुत कुछ सीखना है।
फ्रैक्टल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.