मुझे समझ में नहीं आता कि यह "रैंडम स्ट्रिंग जनरेटर रिटर्निंग समान स्ट्रिंग" से कैसे संबंधित है।
यह सीधे संबंधित नहीं है, हालांकि मूल कारण समान है।
डिफ़ॉल्ट बीज मूल्य सिस्टम घड़ी से ली गई और परिमित संकल्प है: - शिष्टाचार documentation को Why do I keep getting two of same random values in this code?
यह new Random
क्या करता है की an explanation शामिल हैं: एक बेहतर डुप्लिकेट इस सवाल का होगा। नतीजतन, अलग-अलग रैंडम ऑब्जेक्ट्स जिन्हें डिफॉल्ट कन्स्ट्रक्टर को कॉल द्वारा निकट उत्तराधिकार में बनाया गया है, में समान डिफ़ॉल्ट बीज मान होंगे और इसलिए, यादृच्छिक संख्याओं के समान सेट तैयार करेंगे।
दूसरे शब्दों में: यदि आप त्वरित उत्तराधिकार में Random
ऑब्जेक्ट्स बनाते हैं, तो वे वही यादृच्छिक संख्या अनुक्रम उत्पन्न करेंगे।
वह विधि में यादृच्छिक उदाहरण बना रहा था। मैं इसे पूरी तरह से अलग कार्य में बुला रहा हूं ताकि उन्हें एक-दूसरे से स्वतंत्र होना चाहिए।
यह अप्रासंगिक है कि क्या इन वस्तुओं अलग धागे (या Task
रों) में बनाए जाते हैं - वे केवल सिस्टम समय जब वे बनाई गई हैं पर निर्भर करते हैं, और कुछ नहीं पर। वे वास्तव में एक दूसरे से स्वतंत्र हैं, जैसा कि आपने कहा था। लेकिन वे दोनों एक ही बीज मूल्य पर निर्भर करते हैं, जो सृजन में सिस्टम समय है।
इस को सुलझाने का सही तरीका Random
वर्ग के केवल एक उदाहरण है करने के लिए आमतौर पर है।- वास्तव में, इस तरह के कोड: new Random().Next(…)
कोड गंध है, क्योंकि यह Random
वर्ग का गलत उपयोग करता है: आपको प्रत्येक कॉल के लिए एक नया उदाहरण उत्पन्न नहीं करना चाहिए; इसके बजाय, आपको यादृच्छिक संख्याओं के अनुक्रम उत्पन्न करने के लिए एक ही उदाहरण का पुन: उपयोग करना चाहिए।
दुर्भाग्यवश, आप Random
उदाहरण को विभिन्न समवर्ती कार्यों में उपयोग नहीं कर सकते हैं, क्योंकि relevant method थ्रेड सुरक्षित नहीं है - यानी, इसे कई धागे से कॉल करने के साथ-साथ दौड़ की स्थिति भी हो सकती है। इस के आसपास हो रही के कई तरीके हैं, लेकिन सबसे पक्का तरीका एक स्पष्ट लॉक का उपयोग करने के लिए है:
public Class(Random rng) {
lock (rng) {
var timeout = rng.Next(5000);
Debug.Print(timeout.ToString());
}
}
यह ध्यान रखें कि rng
को हर पहुँच बंद किया जाना चाहिए महत्वपूर्ण है, अन्यथा इस विवादास्पद है।
var rng = new Random();
var tasks = new [] {
Task.Run(() => { new Class(rng); }),
Task.Run(() => { new Class(rng); })
};
Task.WaitAll(tasks);
ध्यान दें कि जब lock(…)
ब्लॉक बाहर छोड़ रहा है, यह लग सकता है जैसे कि आप सही परिणाम दे रहे हैं:
अब आप अपने कार्यों को उचित अनियमितता बना सकते हैं और उन्हें चलाने के लिए, और मिलता है। यह समवर्तीता और यादृच्छिकता के साथ काम करने का खतरा है: यह सत्यापित करना मुश्किल है कि आपका परिणाम वास्तव में सही है या फिर यह रास्ते में दूषित हो गया है या नहीं। तो सावधानी के साथ चलना।
** मॉडरेटर नोट **: यदि आप इस प्रश्न पर चर्चा करना चाहते हैं, तो हमारे पास एक चमकदार मेटा पोस्ट है जहां आप ऐसा कर सकते हैं] (http://meta.stackoverflow.com/questions/262791)। कृपया इस प्रश्न पर टिप्पणी * विषय पर रखें: ओपी से स्पष्टीकरण मांगना; इस प्रश्न के दायरे को अपने प्रतिस्पर्धी डुप्लिकेट के साथ-साथ निर्धारित करना। जो कोई सी # में काम करता है, मैं कह सकता हूं कि यह तुरंत स्पष्ट नहीं होगा कि दोनों मुद्दों के समान मूल कारण हैं; और यह एक ऐसा प्रश्न है जो 'कार्यों का उपयोग करके इसे कैसे लिखूं' के उत्तर से भी लाभान्वित होगा। –