2008-11-20 18 views
7

मुझे एक खराब आर्किटेक्टेड समाधान द्वारा काट दिया गया है। यह धागा सुरक्षित नहीं है!थ्रेड-सुरक्षित उपयोग के लिए स्थिर वर्ग के दायरे को सीमित करने के लिए AppDomain का उपयोग कैसे करें?

मेरे पास समाधान में कई साझा वर्ग और सदस्य हैं, और विकास के दौरान सभी शांत थे ...
बिज़टॉक ने मेरे युद्ध जहाज को डूब दिया है।

हम अपने असेंबली को कॉल करने के लिए एक कस्टम बिज़टॉक एडाप्टर का उपयोग कर रहे हैं। एडाप्टर मेरे कोड को कॉल कर रहा है और चीजों को समानांतर में चला रहा है, इसलिए मुझे लगता है कि यह एक ही ऐपडोमेन के तहत कई धागे का उपयोग कर रहा है।

मैं क्या करना चाहता हूं कि मेरा कोड अपने ऐपडोमेन के तहत चलाए, इसलिए साझा की गई समस्याएं एक-दूसरे के साथ नहीं मिलेंगी।

मेरे पास एक बहुत ही सरल वर्ग है कि बिज़टॉक एडाप्टर तत्काल प्रक्रिया() विधि चला रहा है।

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

BizTalkAdapter कोड:

public class Loader 
{ 

    private string connectionString; 
    private string fileName; 
    private Stream stream; 
    private DataFile dataFile; 

    public Loader(Stream stream, string fileName, string connectionString) 
    { 
     this.connectionString = connectionString; 
     this.fileName = fileName; 
     this.stream = stream; 
    } 

    public void Process() 
    { 

     //***** Create AppDomain HERE ***** 
     // run following code entirely under that domain 
     dataFile = new DataFile(aredStream, fileName, connectionString); 
     dataFile.ParseFile(); 
     dataFile.Save(); 
     // get rid of the AppDomain here... 

    } 

} 

FYI करें:

// this is inside the BizTalkAdapter and it is calling the Loader class // 
    private void SendMessage(IBaseMessage message, TransactionalTransmitProperties properties) 
    { 

     Stream strm = message.BodyPart.GetOriginalDataStream(); 
     string connectionString = properties.ConnectionString; 
     string msgFileName = message.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties") as string; 


     Loader loader = new Loader(strm, msgFileName, connectionString); 
     loader.Process(); 

     EventLog.WriteEntry("Loader", "Successfully processed: " + msgFileName); 

    } 

इस वर्ग BizTalk कॉल है लोडर वर्ग datafile वर्ग से एक अलग DLL में है।

किसी भी मदद की सराहना की जाएगी। मैं थ्रेड-सेफ कोड बनाने पर काम करना जारी रखूंगा, लेकिन मुझे लगता है कि यह "सरल" जवाब हो सकता है।

किसी को भी किसी भी अन्य सोचा है, तो में बस संपूर्णता के लिए
कीथ

फेंक दें।

धन्यवाद,।

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

मुझे लगता है कि यह मेरी समस्या का एक और संभावित उत्तर है, लेकिन आवश्यक रूप से प्रश्न के लिए नहीं है।

+0

तो आप स्थैतिक वर्गों और वस्तुओं के बारे में बात नहीं कर रहे हैं, आप एक उदाहरण के बारे में बात कर रहे हैं, है ना? –

उत्तर

3

का उपयोग अनुप्रयोग डोमेन आप कुछ इस तरह कर सकता है:

public class Loader 
{ 

    private string connectionString; 
    private string fileName; 
    private Stream stream; 
    private DataFile dataFile; 

    public Loader(Stream stream, string fileName, string connectionString) 
    { 
     this.connectionString = connectionString; 
     this.fileName = fileName; 
     this.stream = stream; 
    } 

    public void Process() 
    { 
     //***** Create AppDomain HERE ***** 
     string threadID = Thread.CurrentThread.ManagedThreadId.ToString(); 
     AppDomain appDomain = AppDomain.CreateDomain(threadID); 

     DataFile dataFile = 
      (DataFile) appDomain.CreateInstanceAndUnwrap(
         "<DataFile AssemblyName>", 
         "DataFile", 
         true, 
         BindingFlags.Default, 
         null, 
         new object[] 
         { 
          aredstream, 
          filename, 
          connectionString 
         }, 
         null, 
         null, 
         null); 
     dataFile.ParseFile(); 
     dataFile.Save(); 

     appDomain.Unload(threadID);  
    } 
} 
+0

केवी, यदि आप थ्रेडआईडी का उपयोग डोमेन नाम के रूप में कर रहे हैं, तो क्या उसी वर्ग द्वारा इस वर्ग का दूसरा उपयोग समान डोमेन नाम बना सकता है? यदि ऐसा होता है, तो क्या दो ऐपडोमेन एक दूसरे से एक ही नाम से अलग होंगे? कीथ –

+0

मुझे लगता है कि आप डोमेन को उतार रहे हैं, तो यह ठीक रहेगा। जिस स्थिति में मैं चिंतित हूं, उस समय जीसीड होगा .. ठीक है? –

+0

स्ट्रिंग थ्रेडआईडी = थ्रेड। कंटेंट थ्रेड। मैनेज्ड थ्रेडआईड.ओस्ट्रिंग(); –

0

क्यों कोड को चारों ओर लॉक न करें जिसे आप अनुक्रमिक रूप से निष्पादित करना चाहते हैं? यह एक बाधा होगी, लेकिन इसे एक बहुप्रचारित वातावरण में काम करना चाहिए।

public class Loader 
{ 
    private static object SyncRoot = new object(); 
    private string connectionString; 
    private string fileName; 
    private Stream stream; 
    private DataFile dataFile; 

    public Loader(Stream stream, string fileName, string connectionString) 
    { 
     this.connectionString = connectionString; 
     this.fileName = fileName; 
     this.stream = stream; 
    } 

    public void Process() 
    { 

     lock(SyncRoot) { 
      dataFile = new DataFile(aredStream, fileName, connectionString); 
      dataFile.ParseFile(); 
      dataFile.Save(); 
     } 

    } 

} 
+0

मैंने उस बारे में सोचा .. लॉक अन्य धागे का इंतजार कर देगा, लेकिन साझा कक्षाएं साफ़ नहीं की जाती हैं। वे सिरदर्द के कारण चारों ओर रहते हैं। –

3

कौन सा, वास्तव में, धागा सुरक्षा के मामले में एक दर्द की जा रही है? मैं किसी भी स्थिर राज्य और न ही सिंगलेट्स देख सकता हूं - और ऐसा लगता है कि उचित "नई" वस्तुएं हैं ... क्या मैं अंधा हूं?

तो आप क्या लक्षण देख रहे हैं ...

एक ऐपडोमेन उत्तर (अपेक्षाकृत) धीमा होगा। मिडलवेयर समर्थित प्रणाली के हिस्से के रूप में यह ठीक हो सकता है (यानी "अपेक्षाकृत" एक ही गेंद-पार्क में है)। जो क्रम के रूप में "यह स्थिर क्षेत्र धागा प्रति अद्वितीय है" की व्याख्या -

तुम क्या हैं कुछ स्थिर राज्य कहीं, एक और विकल्प कभी कभी काम करता है कि [ThreadStatic] है। आपको प्रारंभिकरण से सावधान रहना होगा, हालांकि - थ्रेड ए पर स्थिर कन्स्ट्रक्टर फ़ील्ड असाइन कर सकता है, लेकिन फिर थ्रेड बी को शून्य/0/आदि दिखाई देगा।

+0

मेरे पास डेटा के नीचे कुछ स्थिर वर्ग हैं, पार्स तर्क के अंदर और तर्क सहेजें। मैं इस थ्रेडस्टैटिक पर एक नज़र डालेगा और देख सकता हूं कि इससे मदद मिल सकती है या नहीं। धन्यवाद। कीथ –

0

यदि आपने एक दूसरे के साथ विवादित सांख्यिकी साझा की है, तो आप उन्हें [थ्रेडस्टैटिक] विशेषता जोड़ने की कोशिश कर सकते हैं। यह उन्हें प्रत्येक धागे के लिए स्थानीय बना देगा। यह आपकी समस्या को अल्प अवधि में हल कर सकता है। एक सही समाधान केवल आपकी सामग्री को थ्रेड-सुरक्षित होने के लिए पुन: व्यवस्थित करना होगा।

0

बस पूर्णता के लिए।

मुझे पता चला कि अगर मैंने प्रेषण एडाप्टर को "ट्रांसपोर्ट एडवांस्ड ऑप्शन" संवाद में "ऑर्डर डिलिवरी" के रूप में चिह्नित किया है तो मैं बहु-थ्रेड मुद्दों से बचने में सक्षम था।

मुझे लगता है कि यह मेरी समस्या का एक और संभावित उत्तर है, लेकिन सवाल के लिए जरूरी नहीं है।

0

प्रत्येक कॉल के लिए एक एपडोमेन बनाना और फाड़ना - मुझे लगता है कि आप इस पर प्रदर्शन के बारे में चिंतित नहीं हैं?

आदर्श रूप से आपको कॉल कोड को थ्रेडसेफ के रूप में बदलना चाहिए।