c# - थ्रेड-सुरक्षित उपयोग के लिए स्थैतिक वर्ग 'क्षेत्र को सीमित करने के लिए ऐपडोमेन का उपयोग कैसे करें?




thread-safety biztalk (4)

क्यों न सिर्फ कोड के आस-पास एक लॉक डाल कर आप क्रमिक रूप से निष्पादित करना चाहते हैं? यह एक बाधा है, लेकिन यह एक मल्टी थ्रेड पर्यावरण में काम करना चाहिए।

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();
        }

    }

}

मुझे खराब वास्तुशिल्प समाधान से काट लिया गया है। यह धागा सुरक्षित नहीं है!

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

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

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

मेरे पास एक बहुत ही सरल वर्ग है जो BizTalk एडाप्टर इंस्टॉलेशन कर रहा है, फिर एक प्रोसेस () विधि चल रहा है।

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

BizTalkAdapter कोड:

  // 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 कॉल है:

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...

    }

}

एफवाईआई: लोडर क्लास डेटाफ़ाइल क्लास से अलग डीएलएल में है।

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

यदि किसी के पास कोई अन्य विचार है, तो कृपया अंदर डालें

धन्यवाद,
कीथ

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

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

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


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

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);       
    }
}

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


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

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

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





appdomain