2012-09-12 16 views
5

में स्टेटिक तरीके पर थ्रेड-सेफ्टी सुनिश्चित करना मेरे पास वर्तमान में एक स्थिर वर्ग/विधि में कुछ कोड है, लेकिन मैं यह जांचना चाहता था कि यह थ्रेड-सुरक्षित होगा। जो मैंने पढ़ा है, उससे मुझे लगता है कि यह ठीक होना चाहिए, लेकिन मेरे दिमाग के पीछे कुछ कह रहा है कि यह नहीं हो सकता है। मेरे वेब पेज का डाटा प्रोसेसिंग चरण ऑर्डर रिकॉर्ड्स बनाने के लिए बाहरी वेब सेवा का उपयोग करता है, और यह काफी धीमा हो सकता है: संभवतः 30-40 सेकंड, संभवतः, 5 या 10 मिनट (यह मेरे हाथों से बाहर है) तो मैं आग लग रहा था एक वापसी पृष्ठ उपयोगकर्ता को वापस, फिर एक नया धागा शुरू करें और फिर प्रक्रिया पूर्ण होने के बाद उपयोगकर्ता को ई-मेल करें। यह वर्तमान में एक स्थिर वर्ग/विधि में है। बशर्ते मेरी सभी वस्तुओं को विशेष विधि के भीतर बनाया गया हो (सिस्टम डिफ़ॉल्ट मानों के अलावा, जो सामान्य होगा) कि विधि थ्रेड-सुरक्षित होना चाहिए, इसे नहीं करना चाहिए। तो, उदाहरण के लिए, अगर मैं थासी #

public static class ProcessOrder() 
{ 
    public static int GetOrderMaxSize() 
    { 
     return (....gets and parses ConfigurationManager.AppSettings["MaxOrderSize"]...); 
    } 

    public static bool CreateOrder(Order order) 
    { 
     XmlDocument xmlDoc = GetOrderXML(order); 
     bool check = false; 
     using (CreateOrderXML.Create xmlCo = new CreateOrderXML.Create()) 
     { 
      xmlCo.Timeout = 60000; 
      System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); 

      string xmlString = ""; 
      using (StringWriter stringWriter = new StringWriter()) 
      { 
       using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter)) 
       { 
        xmlDoc.WriteTo(xmlWriter); 
        xmlWriter.Flush(); 
        xmlString = stringWriter.GetStringBuilder().ToString(); 
       } 
      } 

      byte[] bXMLOrder = encoding.GetBytes(xmlString); 
      byte[] breturnMessage; 

      check = xmlCo.Create(bXMLOrder, out breturnMessage); 
      .... do something with return message 
     } 
     return check; 
    } 

    private static XmlDocument GetOrderXML(Order order) 
    { 
     ... creates an XML object for the order 
    } 
} 

कि विशेष रूप से के लिए, धागा सुरक्षित होगा (CreateOrderXML वेब सेवा URL/विधि के लिए एक सेवा संदर्भ है) लंबे समय से चल (मुख्य रूप से xmlCo.Create पर (....) मंच) समवर्ती धागे? मैं समझता हूं कि अगर मैंने कक्षा के सदस्यों में प्रवेश करना शुरू किया और फिर उन्हें विधि में इस्तेमाल किया, तो यह निश्चित रूप से मूल्यों को ओवरराइट करने वाले विभिन्न धागे के साथ एक समस्या पेश करेगा, लेकिन जब तक ऑब्जेक्ट्स विधियों के भीतर बनाए जाते हैं, तो उन्हें ठीक होना चाहिए, टी वे?

उत्तर

12

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

यहां विधि का प्रत्येक निष्पादन स्थानीय चर बना रहा है - इसकी अपनी प्रतियां हैं। तो कुछ भी साझा नहीं किया जा रहा है।

+0

हाँ, मैं उद्देश्यपूर्ण केवल उपयोग किया है "पूरे सिस्टम में डिफ़ॉल्ट" वर्ग अपने आप में चर, और मैं पारित कि में सब कुछ में हो सकती है कि प्रसंस्करण के लिए आवश्यक है विधि/पैरामीटर के माध्यम से उपयोगकर्ता/सत्र। लेकिन मुझे अभी भी अपने सिर के पीछे जाने वाले चेतावनी देने वाले चेतावनी थी, उम्मीद है कि वे सिर्फ "स्वस्थ परावर्तक" हैं। –

+0

मेरे लिए स्वस्थ परावर्तक की तरह लगता है! –

5

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

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

lock(latch_a) 
{ 
    process(object_a) ; 
    lock (latch_b) 
    { 
    process(object_a,object_b) ; 
    } 
} 

और एक अन्य विधि है कि उलटा करता है: आप एक विधि संसाधन ए और बी का उपयोग करता है है, तो कुछ बिंदु अपने दो धागे गतिरोध होगा, पर

lock(latch_b) 
{ 
    process(object_b) ; 
    lock (latch_a) 
    { 
    process(object_a,object_b) ; 
    } 
} 

जब उनमें से हर एक संसाधन की आवश्यकता है अन्य जरूरतों को बोफोरेर यह कहा संसाधन तक पहुंच छोड़ सकता है।

नोट करने के लिए संपादित: जानकारी के लिए lock बयान के लिए सी # दस्तावेज़ देखें। आम तौर पर, लॉक ऑब्जेक्ट साझा संसाधन पहुंच का प्रतिनिधित्व करता है (और हो सकता है) जिस पर धारावाहिक किया जा रहा है। एक आम पैटर्न की तरह कुछ करने के लिए है:

class Widget 
{ 
    private static readonly object X = new object() ; 

    public void Foo() 
    { 
    lock(X) 
    { 
     // Do work using shared resource 
    } 
    return ; 
    } 

} 
+0

क्या latch_a और latch_b ऑब्जेक्ट्स हैं जिन्हें एक बार बनाया जाना चाहिए और फिर स्थिर कॉल पर प्रत्येक कॉल में पास किया जाना चाहिए? – Doug

+0

@Doug: मेरा संशोधित उत्तर देखें। –