2010-09-25 11 views
11

हम उत्पादन वातावरण में अजीब बग का अनुभव कर रहे हैं, हम डीबग नहीं कर सकते हैं और न ही लॉगिंग कोड इंजेक्ट कर सकते हैं। मैं इसे समझने की कोशिश कर रहा हूं लेकिन स्टैक ट्रेस के बाद मुझे भ्रमित कर रहा हूं।किस परिस्थिति में सिस्टम.कोलेक्शन .अरेलेलिस्ट। इंडेक्सऑटऑफेंजेंज एक्सेप्शन फेंकता है?

System.IndexOutOfRangeException: Index was outside the bounds of the array. 
    at System.Collections.ArrayList.Add(Object value) 
    at ... 

According to the MSDNAdd विधि केवल NotSupportedException फेंक चाहिए।

मुझे नहीं पता कि यहां क्या हो रहा है। क्या आप? जब "एक प्रयास एक सूचकांक सरणी की सीमा से बाहर है कि के साथ एक सरणी का एक तत्व का उपयोग किया जाता है।"

+0

क्या आप कुछ हद तक पूर्ण स्टैकट्रैक पोस्ट कर सकते हैं? – shahkalpesh

+3

बस अनुमान लगा रहा है: मल्टीथ्रेडिंग परिचालनों पर ArrayList का उपयोग किया जाता है? –

+0

अपवाद होने पर आप डिबगर में अन्य थ्रेड स्टेटस का निरीक्षण करके समवर्ती बग की पुष्टि करने में सक्षम हो सकते हैं। जांचें कि उस समय कोई और कंटेनर बदल रहा है या नहीं। दिन के अंत में –

उत्तर

7

यह धागा सुरक्षित नहीं किया जा रहा सूची करने पर निर्भर करता की कोशिश करें। जब के बाद जोड़ने से अधिक थ्रेड का उपयोग कर आइटम के रूप में नीचे तुल्यकालन के बिना,

List<TradeFillInfo> updatedFills = new List<TradeFillInfo>(); 
Parallel.ForEach (trades, (trade) => 
{ 
    TradeFillInfo fill = new TradeFillInfo(); 

    //do something 

    updatedFills.Add(fill); //NOTE:Adding items without synchronization 
}); 

foreach (var fill in updatedFills) //IndexOutOfRangeException here sometimes 
{ 
    //do something 
} 

एक सूची से अधिक पुनरावृत्ति इस मामले में मैं IndexOutOfRangeException घटित पड़ा है, updatedFills गिनती दूषित हो जाता है और बाद में यात्रा विफल रहता है। लॉक स्टेटमेंट के आस-पास जोड़ें() को लपेटना इसे रोकना चाहिए।

lock (updatedFills) 
{ 
    updatedFills.Add(fill); 
} 
19

IndexOutOfRangeException फेंक दिया जाता है

ध्यान दें कि ArrayList कक्षा थ्रेड-सुरक्षित नहीं है। यह संभव है कि बहु-थ्रेडेड परिदृश्यों में, दौड़-परिस्थितियों के परिणामस्वरूप ArrayList इसकी सीमा के बाहर मौजूद इंडेक्स पर बैकिंग सरणी को पढ़ने/लिखने का प्रयास करेगा।

उदाहरण: एक धागा बैकिंग सरणी के आकार को कम कर देता है (शायद TrimToSize कॉल के माध्यम से) उसी समय एक और थ्रेड संग्रह में जोड़ रहा है। अब, यदि बैकिंग सरणी पूरी क्षमता पर है, तो जोड़ना धागा नए तत्व को समायोजित करने के लिए अपनी क्षमता (एक नई सरणी आवंटित करके) का विस्तार करने का प्रयास करेगा। एक साथ TrimToSize कॉल फिर इस प्रभाव को उलट देता है। फिर, जब तक थ्रेड जोड़ने वाले सरणी को लिखने का प्रयास करता है, तो सूचकांक सोचा उपलब्ध नहीं था, अपवाद को फेंकने का कारण नहीं होगा।

फिक्स्ड: स्थिति के लिए उपयुक्त थ्रेड-सुरक्षित संरचनाओं का उपयोग करें।

11

लगभग निश्चित रूप से एक संगामिति मुद्दा है यही कारण है कि ... आप शायद दो धागे कि एक ही समय में संग्रह को संशोधित है, और ArrayList वर्ग समवर्ती पहुंच का समर्थन करता नहीं बनाया गया है। एक दौड़ की स्थिति होती है, जो कभी-कभी धागे में से एक को सरणी की सीमाओं के बाहर एक स्थिति में लिखने का प्रयास करती है।

सभी lock बयानों का उपयोग कर संग्रह के लिए पहुँचता की रक्षा, या संग्रह की एक सिंक्रनाइज़ आवरण का उपयोग करें (ArrayList.Synchronized पद्धति का उपयोग करके)

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