10

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

क्या टीपीएल का उपयोग करते समय टीएलएस की प्रतिलिपि बनाने का कोई तरीका है? जब यह प्रतीक्षा सुविधा प्राप्त हो जाता है तो यह सी # पर भी लागू होगा।

धन्यवाद, एरिक

उत्तर

5

आमतौर पर, यह Parallel.For की एक अधिभार कि पहले से ही धागा स्थानीय डेटा का उपयोग कर के लिए प्रदान करता माध्यम से नियंत्रित किया जाता है।

यह अधिभार आपको प्रारंभिक और अंतिमकरण प्रतिनिधि प्रदान करने की अनुमति देता है, जो प्रभावी रूप से आपके धागे के स्थानीय डेटा के लिए प्रति थ्रेड प्रारंभिक हो जाता है, और अंत में परिणामों को "विलय" करने के अंत में एक कमी समारोह (जो प्रति बार एक बार चलाया जाता है) धागा)। I wrote about this in detail here

object sync = new object(); 
double result = 0; 

Parallel.For(0, collection.Count, 
    // Initialize thread local data: 
    () => new MyThreadSpecificData(), 
    // Process each item 
    (i, pls, currentThreadLocalData) => 
    { 
     // Generate a NEW version of your local state data 
     MyThreadSpecificData newResults = ProcessItem(collection, i, currentThreadLocalData); 
     return newResults; 
    }, 
    // Aggregate results 
    threadLocalData => 
    { 
     // This requires synchronization, as it happens once per thread, 
     // but potentially simultaneously 
     lock(sync) 
      result += threadLocalData.Results; 
    }); 
+0

धन्यवाद रीड - यह वही करता है जो मुझे चाहिए, हालांकि मुझे समस्या से निपटने के लिए एक अलग तरीका मिला। फिर भी, यह उत्कृष्ट चीजें हैं जिन्हें मैं जल्द ही उपयोग करूँगा। –

+0

मुझे आश्चर्य है कि उन्होंने इतने बदसूरत अधिभार क्यों शामिल किए? उस दर पर यह केवल थ्रेड-स्थानीय डेटा को आरंभ करने के लिए क्लीनर होगा और इसे आपके मुख्य प्रतिनिधि में पुन: प्रारंभ कर देगा। जब तक वे perf अनुकूलित नहीं है ..? –

+0

@ टिमलोवेल-स्मिथ थ्रेड स्थानीय डेटा को कई प्रतिनिधि कॉलों में पुन: उपयोग किया जाता है, इसलिए इसे एक प्रतिनिधि के अंदर प्रारंभ/अंतिम रूप में प्रारंभ नहीं किया जा सकता है। (यही बात है;)) –

4

मैं समस्या यह है कि कोड की आवश्यकता नहीं है के लिए एक और समाधान मिला:

बुनियादी रूप की तरह कुछ करने के लिए है। मैं "लॉजिकल थ्रेड" में डेटा संलग्न करने के लिए CallContext का उपयोग करने में सक्षम था। यह डेटा शुरुआती धागे से टीपीएल के साथ-साथ थ्रेडपूल द्वारा उत्पन्न धागे से स्थानांतरित किया जाता है।

http://www.wintellect.com/CS/blogs/jeffreyr/archive/2010/09/27/logical-call-context-flowing-data-across-threads-appdomains-and-processes.aspx

+5

बस एफवाईआई - यह तंत्र टीएलएस का उपयोग करने से बहुत धीमा है, क्योंकि यह प्रत्येक संदर्भ कॉल के माध्यम से डेटा को क्रमबद्ध कर रहा है ... –

0

वहाँ है निश्चित रूप से, अभी तक एक और विकल्प: एक TaskLocal (टी) वर्ग लिखें, जैसे हम किया था, कि वर्तमान कार्य पर भंडारण, बल्कि वर्तमान थ्रेड से आधार बनाता है। ईमानदारी से, मुझे नहीं पता कि माइक्रोसॉफ्ट ने अपने शुरुआती कार्य कार्यान्वयन के हिस्से के रूप में ऐसा क्यों नहीं किया।

महत्वपूर्ण कार्यान्वयन टिप्पणी: क्योंकि टास्क कोड इंतजार है कि कॉल विभाजित किया जा सकता है, और फिर से शुरू के रूप में एक अलग TaskId, आप भी क्या हम भी किया करते हैं, और TaskLocal (टी) है कि नए TaskIds नक्शे में एक विधि लागू करने की आवश्यकता पिछले लोगों के लिए, फिर कार्य की शुरुआत में मूल कार्यसूची को सहेजें, और प्रत्येक प्रतीक्षा कॉल के बाद इसे मानचित्र करें।

+0

यह दिखाते हुए एक कोड नमूना मुझसे +1 प्राप्त करेगा :-) – JoshBerke

+0

मैं देखता हूं कि मैं क्या कर सकता हूं ... ( – Thought

+0

यह बहुत अच्छा होगा! – JoshBerke

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