2012-11-28 43 views
18

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

क्या कोई कस्टम कस्टम डेटा प्रवाह ब्लॉक के आसपास कोई तरीका है? या क्या मैं गलत समझ रहा हूं कि ब्रॉडकास्टब्लॉक कैसे काम करता है? दुर्भाग्यवश वहां वास्तव में बहुत अधिक दस्तावेज नहीं हैं जो विस्तार से आगे बढ़ते हैं और मामलों का उपयोग करते हैं। किसी भी विचार की अत्यधिक सराहना की जाती है।

उत्तर

22

यदि मैं आपको सही ढंग से समझता हूं, तो आप जो चाहते हैं उसे सरल BufferBlock द्वारा पूरा किया जा सकता है, जो भविष्य के साथ आपके सभी लक्षित ब्लॉक से जुड़ा होगा। मिलान करने वाली वस्तुओं को त्यागने के लिए आप इसे बिना किसी शर्त के NullTarget block पर लिंक भी करेंगे।

कुछ की तरह:

var forwarder = new BufferBlock<SomeType>(); 
forwarder.LinkTo(target1, item => matchesTarget1(item)); 
forwarder.LinkTo(target2, item => matchesTarget2(item)); 
forwarder.LinkTo(DataflowBlock.NullTarget<SomeType>()); 

इस तरह, प्रत्येक आइटम पहले लक्ष्य है कि, से मेल खाता है, अगर वहाँ किसी भी करने के लिए भेजा जाएगा।

BroadcastBlock उपयोगी हो सकता है यदि आप प्रत्येक आइटम को एकाधिक लक्ष्यों पर भेजना चाहते हैं, या यदि आप लक्ष्य ब्लॉक पर्याप्त तेज़ नहीं हैं तो आइटम को त्यागना चाहते हैं।

BroadcastBlock के साथ, यदि कोई ब्लॉक उन्हें स्वीकार नहीं करता है तो आइटम गिराए जा सकते हैं (भले ही वे इसे बाद में स्वीकार कर सकें)। लेकिन यह आइटम को यादृच्छिक रूप से नहीं छोड़ता है, इसलिए यदि आपके लक्षित ब्लॉक में BoundedCapacity सेट नहीं है, तो मुझे लगता है कि आप यह सुनिश्चित कर सकते हैं कि वे उन सभी आइटमों को प्राप्त करेंगे जिन्हें वे अस्वीकार नहीं करते हैं (उदाहरण के लिए LinkTo() में भविष्यवाणी का उपयोग करके)।

+0

यह तकनीकी रूप से कैसे काम करता है? क्या प्रत्येक लक्ष्य तब तक प्रयास करता है जब तक कि कोई मिलान न हो और यदि नल लक्ष्य ब्लॉक द्वारा फ़्लश किए जाने तक इसकी याददाश्त मेमोरी न हो? और क्या मैं जिस लक्ष्य ब्लॉक को लिंक करता हूं उसका क्रम तो पहले ... मामला? –

+3

हाँ, अनुक्रम में प्रत्येक लक्ष्य की कोशिश की जाती है। यदि कोई लक्ष्य मिलान नहीं होता है, तो आइटम बफर ब्लॉक में रहेगा। और उस स्थिति में, स्मृति को अपनाना एक बड़ी चिंता नहीं है, पाइपलाइन को अपनाना है। दूसरे शब्दों में, इसका मतलब यह होगा कि इस ब्लॉक से कोई अन्य आइटम नहीं भेजा जाएगा जब तक कि कुछ लक्ष्य द्वारा समस्याग्रस्त व्यक्ति को स्वीकार नहीं किया जाता है। यही कारण है कि 'नलटाइटल' ब्लॉक आवश्यक है। और हां, ऑर्डर मायने रखता है, यही कारण है कि आप [निर्दिष्ट कर सकते हैं कि आप सूची में प्रत्येक लक्ष्य को जोड़ना या प्रीपेड करना चाहते हैं] (http://msdn.microsoft.com/en-us/library/system.threading.tasks .dataflow.dataflowlinkoptions.append.aspx)। – svick

+0

आप टीडीएफ में जाने के लिए वास्तव में लड़के हैं। बहुत बढ़िया। बहुत बहुत धन्यवाद। क्या आप बड़े पैमाने पर टीपीएल डेटाफ्लो का उपयोग कर रहे हैं या इस पुस्तकालय के गहरे ज्ञान (अन्य विषयों के बीच) क्यों? आपने पहले उल्लेख किया था कि आप एमएस कंसुरेंसी टीम से संबद्ध नहीं हैं। –

6

मुझे स्वीकार्य उत्तर गलत होने का पता चला है। NullTarget को अपने भविष्य के साथ अपने उपभोक्ताओं की अस्वीकृति के साथ जोड़ा जाना चाहिए। अन्यथा आप उन संदेशों को छोड़ सकते हैं जिन्हें आप उपभोग करना चाहते थे।

var forwarder = new BufferBlock<SomeType>(); 
forwarder.LinkTo(target1, item => matchesTarget1(item)); 
forwarder.LinkTo(target2, item => matchesTarget2(item)); 
forwarder.LinkTo(DataflowBlock.NullTarget<SomeType>(), item => !matchesTarget1(item) && !matchesTarget2(item)); 
+0

क्या आप कृपया संदेश छोड़ने के बारे में विस्तृत जानकारी दे सकते हैं? फ़िल्टर अनुक्रम में आवेदन कर रहा है, इसलिए, यदि उचित क्रम में लिंक किया गया है, तो वैध संदेश छोड़ने का कोई तरीका नहीं है, है ना? – VMAtm

+0

@VMAtm तो अंत में, अनुक्रम द्वारा क्रम को जोड़ता है? बस सुनिश्चित करना चाहते हैं .. –

+0

@ बी.बेन हां, यह इस तरह काम करता है – VMAtm