14

सटीक त्रुटि बनाने:सूची सूचकांक रेंज अपवाद में से जब एक कार्य

Index was out of range. Must be non-negative and less than the size of the collection.

मैं सूचकांक सरणियों है और अनगिनत बार सूचीबद्ध करता है। मैंने सरणी के साथ लूप के लिए उपयोग किया है और अनगिनत बार सूचीबद्ध करता है। डेटा वहां है, यह काम करता है। सिवाय जब मैं अपने फ़ंक्शन के लिए कोई कार्य बनाने का प्रयास करता हूं। आपको याद है, मैंने सफलतापूर्वक इसी तरह के फ़ंक्शन के लिए फ़ोरैच लूप के साथ ऐसा किया है; इस नए व्यक्ति को दो तर्कों की आवश्यकता है, इसलिए मैं फ़ोरैच लूप का सही उपयोग नहीं कर सकता। कम से कम मुझे नहीं लगता कि मैं कर सकता हूं।

if (addressList != null) { 
    textBox1.Text += ("Address List Length: " + addressList.Count + Environment.NewLine); 

    for (int i = 0; i < addressList.Count; i++) { 
     textBox1.Text += ("Task for " + addressList[i] + ":" + portList[i] + " initiated." + Environment.NewLine); 

     Task.Factory.StartNew(() => PingTaskAdapted(addressList[i], portList[i])); 
    }     
} 
else textBox1.Text = ("No IPs have been added."); 

मान लिया जाये कि addressList[0] google.com है और portList[0] 80 है, आउटपुट::

Address List Length: 1 
Task for google.com:80 initiated. 

तो कार्यक्रम को तोड़ने, मुझे उस कह PingTaskAdapted पर दृश्य स्टूडियो के साथ

यहाँ गलत कोड है() मैं एक इंडेक्स को कॉल कर रहा हूं जो सीमा से बाहर है, जब यह सचमुच सिर्फ इंडेक्स को प्रश्न में मुद्रित करता है, क्योंकि वे मौजूद हैं।

और बस स्पष्ट होने के लिए, अगर मैं PingTaskAdapted(addressList[0], pingList[0]); पर कॉल करता हूं तो यह कोई समस्या नहीं है।

+0

आप Enumerable.Zip' का उपयोग करना चाहिए '। – Alexander

उत्तर

17

कार्य पूरा होने पर आपका कार्य सूची तक पहुंच जाएगा। लूप में दिखाई देने वाले कोड की रेखा में अनुक्रमिक रूप से नहीं। यह सुनिश्चित करने के लिए कि बंद करने में सही मान कैप्चर किए गए हैं (और सूचियां अभी भी मौजूद हैं और समान मान हैं), स्थानीय प्रतियां कार्य के बाहर बनाएं, यह सुनिश्चित करें कि लूप रन के समय उस बिंदु पर मान कैप्चर किए जाते हैं:

var localAddress = addressList[i]; 
var localPort = portList[i]; 
Task.Factory.StartNew(() => PingTaskAdapted(localAddress , localPort)); 
+1

मैं अपने स्वयं के उत्तर के बावजूद इसे करने का यह तरीका पसंद करूंगा (जिसे मैंने स्पष्ट किया था कि किस चर के बारे में स्पष्टता के लिए मैंने किया था)। इस उत्तर का कोड स्निपेट इसे प्रचुर मात्रा में स्पष्ट करता है * जो * कार्य निष्पादन में मूल्य का उपयोग किया जाएगा। –

+0

यह एक बहुत ही अजीब घटना है। के बारे में जानने के लिए दिलचस्प है। मेरा कोड वास्तव में अब काम करता है, धन्यवाद। – soxroxr

7

आप संशोधित बंद करने तक पहुंचने का शिकार हैं, क्योंकि इसे संक्षिप्त रूप से बुलाया जाता है। असल में, चूंकि आप एक कार्य का उपयोग कर रहे हैं - और बूट करने के लिए एक प्रतिनिधि - i का मान यह गारंटी नहीं है कि आप इसकी अपेक्षा करते हैं। यदि आप, i को एक स्थानीय चर के लिए प्रतिलिपि बनाते हैं, एक के दायरे के लिए विशिष्ट, एकल पुनरावृत्ति, आपको ठीक होना चाहिए।

for (int i = 0; i < addressList.Count; i++) 
{ 
    textBox1.Text += ("Task for " + addressList[i] + ":" + portList[i] + " initiated." + Environment.NewLine); 

    var iCopy = i; 
    Task.Factory.StartNew(() => PingTaskAdapted(addressList[iCopy], portList[iCopy])); 
} 


लेकिन, जैसा कि this answer by nvoigt में बताया, यह कहीं अधिक स्पष्ट करता है, तो आप मान जो इटरेटर मूल्य के बजाय इस्तेमाल किया जाएगा कॉपी जब यह पठनीयता और रख-रखाव के लिए आता है।

+0

क्या आपके पास इसके बारे में कोई संदर्भ है? आईडी इसे पढ़ने के लिए पसंद है। – thanatorr

+3

@ थानोटर [यहां] (https://stackoverflow.com/a/271447/767890) – InBetween

+0

संशोधित बंद करने तक पहुंचने के बारे में अतिरिक्त जानकारी के लिए धन्यवाद। – soxroxr

5

क्लोजर चर, नहीं मूल्यों पर कब्जा।

बदलें निम्नलिखित करने के लिए कोड, और आप देखेंगे मुद्दा चले जाओ:

for (int i = 0; i < addressList.Count; i++) { 
    textBox1.Text += ("Task for " + addressList[i] + ":" + portList[i] + " initiated." + Environment.NewLine); 

    var temp = i; 
    Task.Factory.StartNew(() => PingTaskAdapted(addressList[temp], portList[temp])); 
    }     
संबंधित मुद्दे