32

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

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

और क्या आइटम भेजते समय दो तरीकों के बीच कोई प्रदर्शन अंतर है?

उत्तर

39

अंतर देखने के लिए, आपको ऐसी स्थिति की आवश्यकता है जहां ब्लॉक उनके संदेशों को स्थगित कर देगा। इस मामले में, Postfalse तुरंत लौटाएगा, जबकि SendAsyncTask लौटाएगा जो ब्लॉक पूरा होने पर संदेश के साथ क्या करना है, पूरा हो जाएगा। Task में true परिणाम होगा यदि संदेश स्वीकार किया गया है, और false परिणाम नहीं है।

स्थगित स्थिति का एक उदाहरण एक लालची शामिल है।एक सरल उदाहरण है जब आप BoundedCapacity सेट:

[TestMethod] 
public void Post_WhenNotFull_ReturnsTrue() 
{ 
    var block = new BufferBlock<int>(new DataflowBlockOptions {BoundedCapacity = 1}); 

    var result = block.Post(13); 

    Assert.IsTrue(result); 
} 

[TestMethod] 
public void Post_WhenFull_ReturnsFalse() 
{ 
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); 
    block.Post(13); 

    var result = block.Post(13); 

    Assert.IsFalse(result); 
} 

[TestMethod] 
public void SendAsync_WhenNotFull_ReturnsCompleteTask() 
{ 
    // This is an implementation detail; technically, SendAsync could return a task that would complete "quickly" instead of already being completed. 
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); 

    var result = block.SendAsync(13); 

    Assert.IsTrue(result.IsCompleted); 
} 

[TestMethod] 
public void SendAsync_WhenFull_ReturnsIncompleteTask() 
{ 
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); 
    block.Post(13); 

    var result = block.SendAsync(13); 

    Assert.IsFalse(result.IsCompleted); 
} 

[TestMethod] 
public async Task SendAsync_BecomesNotFull_CompletesTaskWithTrueResult() 
{ 
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); 
    block.Post(13); 
    var task = block.SendAsync(13); 

    block.Receive(); 

    var result = await task; 
    Assert.IsTrue(result); 
} 

[TestMethod] 
public async Task SendAsync_BecomesDecliningPermanently_CompletesTaskWithFalseResult() 
{ 
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); 
    block.Post(13); 
    var task = block.SendAsync(13); 

    block.Complete(); 

    var result = await task; 
    Assert.IsFalse(result); 
} 
+0

ठीक है लेकिन आपकी स्पष्टीकरण दी गई है, तो 'कार्य ' के पीछे तर्क क्या है? अगर यह स्थगन के कारण तुरंत जमा नहीं हो सकता है लेकिन कार्य बाद में पूरा हो जाता है तो बूल के बीच क्या अंतर सही और गलत होता है? –

+1

ब्लॉक अंततः उस संदेश को अस्वीकार करने का निर्णय ले सकता है (उदाहरण के लिए, यदि आप ब्लॉक को पूरा करते हैं), तो इस मामले में कार्य का परिणाम 'झूठा' होगा। अद्यतन उत्तर देखें। –

+0

बढ़िया, अब यह पूरी तरह से समझ में आता है, कि संभावना पूरी तरह से मेरे दिमाग फिसल गई। बहुत बहुत धन्यवाद। –

7

प्रलेखन यह उचित स्पष्ट, आईएमओ बनाता है। विशेष रूप से, Post के लिए:

इस विधि एक बार लक्ष्य ब्लॉक को स्वीकार करने या आइटम अस्वीकार करने के लिए फैसला किया है वापस आ जाएगी, लेकिन जब तक अन्यथा लक्ष्य ब्लॉक के विशेष अर्थ विज्ञान से तय, यह वास्तव में करने के लिए आइटम के लिए इंतजार नहीं कर रहा है प्रोसेस किया गया।

और:

है कि पेशकश संदेशों स्थगित, या ब्लॉक कि उनके Post कार्यान्वयन में अधिक संसाधन ऐसा कर सकते हैं के लिए समर्थन लक्ष्य ब्लॉकों के लिए, SendAsync है, जो तुरंत वापस आ जाएगी उपयोग करने पर विचार करने के लिए और लक्ष्य सक्षम हो जाएगा पोस्ट किए गए संदेश को स्थगित कर दें और बाद में इसे SendAsync रिटर्न के बाद उपभोग करें।

दूसरे शब्दों में, जबकि दोनों प्रसंस्करण संदेश के संबंध में अतुल्यकालिक कर रहे हैं, SendAsync तय करने के लिए किया जाए या नहीं को संदेश स्वीकार एसिंक्रोनस रूप से भी लक्ष्य ब्लॉक अनुमति देता है।

ऐसा लगता है कि SendAsync आमतौर पर "अधिक असीमित" दृष्टिकोण है, और जिसे सामान्य रूप से प्रोत्साहित किया जाता है। मुझे स्पष्ट नहीं है कि दोनों की आवश्यकता क्यों है, क्योंकि यह निश्चित रूप से Post जैसा लगता है SendAsync का उपयोग करने के बराबर है और फिर परिणाम पर प्रतीक्षा कर रहा है।

+0

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

+0

मुझे लगता है कि मैं समझ नहीं पा रहा हूं कि नए पारित संदेशों की "स्वीकृति/गिरावट" तंत्र में कितनी विलंबता संभवतः पेश की जा सकती है। अब तक मैंने कतार से इनपुट कतार/अस्वीकृति में किसी संदेश के उत्तीर्ण होने और आगमन के बीच किसी भी मापनीय देरी को कभी नहीं देखा है। लेकिन इस मुद्दे के "स्वीकृति/अस्वीकृति" भाग पर ध्यान केंद्रित करने के लिए वैसे भी धन्यवाद। –

+3

@Freddy: ज़रूर - लेकिन अंतर तब होता है जब एक ब्लॉक * स्थगित * स्वीकार/अस्वीकार निर्णय। हो सकता है कि आप जिस लक्षित ब्लॉक का उपयोग कर रहे हैं वह निश्चित रूप से ऐसा नहीं करता है। –

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