2012-01-12 16 views
25

नियमित "थ्रेड सुरक्षा" MSDN प्रलेखन के StringBuilder कहा गया है कि के लिए अनुभाग:है नेट के StringBuilder धागा सुरक्षित

... किसी भी घटना के सदस्यों धागा सुरक्षित होने की गारंटी नहीं कर रहे हैं ...

लेकिन इस बयान लगता है जैसे यह कॉपी किया गया है और फ्रेमवर्क में लगभग हर वर्ग के लिए चिपकाया:

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

SSCLI में

http://www.gavpugh.com/2010/03/23/xnac-stringbuilder-to-string-with-no-garbage/

http://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/

साथ ही, StringBuilder का स्रोत परावर्तक से पता चला, और साथ टिप्पणी : ०५३६९१३६३२१०

हालांकि, गेविन प्यूघ द्वारा इन ब्लॉग पोस्ट StringBuilder के धागे की सुरक्षित व्यवहार का उल्लेख स्रोत, थ्रेड-सुरक्षा सुनिश्चित करने के लिए कई कार्यान्वयन विचारों का भी सुझाव देता है:

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Text&type=StringBuilder

क्या किसी के पास कोई और अंतर्दृष्टि है कि StringBuilder उदाहरण एकाधिक समवर्ती धागे के बीच साझा करना सुरक्षित है या नहीं?

उत्तर

21
नहीं

बिल्कुल; यहां 4.0 से परावर्तक के माध्यम से उठाया गया एक सरल उदाहरण है:

[SecuritySafeCritical] 
public StringBuilder Append(char value) 
{ 
    if (this.m_ChunkLength < this.m_ChunkChars.Length) 
    { 
     this.m_ChunkChars[this.m_ChunkLength++] = value; 
    } 
    else 
    { 
     this.Append(value, 1); 
    } 
    return this; 
} 

विशेषता केवल कॉलर्स को संभालती है, थ्रेड-सुरक्षा नहीं; यह बिल्कुल धागा-सुरक्षित नहीं है।

अपडेट: उस स्रोत को देखकर वह संदर्भित करता है, यह स्पष्ट रूप से वर्तमान .NET 4.0 कोड-बेस (कुछ विधियों की तुलना नहीं) है। शायद वह एक विशेष .NET संस्करण, या शायद एक्सएनए के बारे में बात कर रहा है - लेकिन यह सामान्य रूप से मामला नहीं है। 4.0 StringBuilderm_currentThread फ़ील्ड है, जो गेविन के स्रोत सामग्री का उपयोग करता है; एक संकेत है (एक अप्रयुक्त स्थिर ThreadIDField) कि यह उपयोग करने के लिए का उपयोग किया गया था, लेकिन ... अब नहीं।


आप एक प्रत्यक्ष खंडन चाहते हैं - 4.0 पर इस चलाने; यह संभवतः गलत लंबाई दे सकता है (मैंने 4k क्षेत्र में कुछ देखा है, कुछ 2k क्षेत्र में हैं - यह बिल्कुल 5000 होना चाहिए), लेकिन कुछ अन्य Append विधियों (Append(char) उदाहरण के लिए) अपवाद फेंकने की अधिक संभावना है , समय के आधार पर:

var gate = new ManualResetEvent(false); 
var allDone = new AutoResetEvent(false); 
int counter = 0; 
var sb = new StringBuilder(); 
ThreadStart work = delegate 
{ 
    // open gate when all 5 threads are running 
    if (Interlocked.Increment(ref counter) == 5) gate.Set(); 
    else gate.WaitOne(); 

    for (int i = 0; i < 1000; i++) sb.Append("a"); 

    if (Interlocked.Decrement(ref counter) == 0) allDone.Set(); 
}; 
for(int i = 0 ; i < 5 ; i++) 
{ 
    new Thread(work).Start(); 
} 
allDone.WaitOne(); 
Console.WriteLine(sb.Length); 
+0

'स्ट्रिंग.बिल्डर '3.5 तक अभी भी थ्रेड-चेकिंग कोड शामिल है। अधिक जानकारी के लिए http://stackoverflow.com/a/3564934/3205 देखें। – skolima

5

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

कुछ चीजें threadsafe हो सकता है एक कार्यान्वयन विस्तार है यही कारण है कि जो कर सकते हैं और हो सकता है ढांचे का एक संस्करण से बदल रहा है अगले करने के लिए या एक कार्यान्वयन से ऐसी जानकारी के बहुत सारे अगले (वास्तव में देखते हैं करने के लिए बदल जाती है फ्रेमवर्क संस्करणों में; एरिक लिपर्ट के कुछ पदों में से कुछ को विवरण दिया गया है)। इस पर भरोसा मत करो।

(दूसरे शब्दों में:।, एक कार्यान्वयन के लिए कोड लिखने मत करो यह इंटरफेस और अनुबंध जो वर्ग के मेटाडाटा और इस मामले में इसके प्रलेखन है के खिलाफ लिखने)

0

MSDN documentation से:

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

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