2009-09-21 8 views
12

एक प्रश्न का उत्तर this संदर्भित।क्या बाइनरीफॉर्मेटर सीरियलाइज और डिसेरियलाइज थ्रेड सुरक्षित है?

private static BinaryFormatter formatter = new BinaryFormatter(); 

    public static T DeepClone<T>(this T a) 
    { 
     using(MemoryStream stream = new MemoryStream()) 
     { 
      formatter.Serialize(stream, a); 
      stream.Position = 0; 
      return (T)formatter.Deserialize(stream); 
     } 
    } 

तो निर्माण से परहेज (और GC'ing) प्रत्येक कॉल के लिए एक नया BinaryFormatter:

इस के रूप में लिखा जा सकता है?

यह कोड पथ बहुत बार हिट हो रहा है क्योंकि इसमें हमारी कैशिंग परत शामिल है और मैं इसे जितना संभव हो उतना हल्का बनाना चाहता हूं।

धन्यवाद।

+1

अपरिवर्तनीय के लिए एक क्लासिक तर्क;) –

उत्तर

9

MSDN के अनुसार:

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

तो आपको Serialize/Deserialize विधियों तक पहुंच को सिंक्रनाइज़ करने की आवश्यकता है।

क्या आपने हर बार स्थानीय धारावाहिक उदाहरण बनाकर विशेष प्रदर्शन समस्याओं की पहचान की है?


अद्यतन:

मैं MSDN पर भरोसा है, क्योंकि भले ही कुछ मामलों में हम चाहते हैं कि उदाहरण के सदस्यों की पुष्टि कर सकते धागा सुरक्षित इसका मतलब यह है कि अगले सेवा के साथ पैक/अद्यतन/ढांचा संस्करण इस नहीं है हो सकता है मामला जारी रहेगा।

BinaryFormatter निर्माता पर परावर्तक के साथ देख रहे हैं:

public BinaryFormatter() 
{ 
    this.m_typeFormat = FormatterTypeStyle.TypesAlways; 
    this.m_securityLevel = TypeFilterLevel.Full; 
    this.m_surrogates = null; 
    this.m_context = new StreamingContext(StreamingContextStates.All); 
} 

और StreamingContext निर्माता:

public StreamingContext(StreamingContextStates state, object additional) 
{ 
    this.m_state = state; 
    this.m_additionalContext = additional; 
} 

काफी स्पष्ट रूप से बताए 6 गुण (जिनमें से अधिकांश enums कर रहे हैं) blindingly उपवास किया जाना चाहिए। आईएमएचओ ज्यादातर समय Serialize/deserialize तरीकों में खर्च किया जाएगा।

+0

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

6

आप [थ्रेडस्टैटिक] विशेषता का उपयोग कर सकते हैं और प्रारंभ कर सकते हैं यदि मान शून्य है। यह आपके पुन: उपयोग करने वाले धागे को मानने में काम करेगा।

[ThreadStatic] 
private static BinaryFormatter formatter = null; 

public static T DeepClone<T>(this T a) 
    { 
      if(formatter == null) formatter = new BinaryFormatter(); 
      using(MemoryStream stream = new MemoryStream()) 
      { 
        formatter.Serialize(stream, a); 
        stream.Position = 0; 
        return (T)formatter.Deserialize(stream); 
      } 
    } 
बेशक

, दूसरा विकल्प लाल गेट से Relfector.Net का उपयोग करें और द्विआधारी formatter के कार्यान्वयन की समीक्षा करने के लिए है। कोड पढ़ने के बाद आपको यह तय करने में सक्षम होना चाहिए कि क्या यह क्रॉस थ्रेडेड उपयोग के लिए सुरक्षित है; हालांकि, डारिन सही है कि यह भविष्य में रिलीज में टूट सकता है।