2012-07-29 9 views
17

यह एक समस्या है जिसे मैं पिछले सप्ताह में जांच कर रहा हूं और कोई समाधान नहीं मिल रहा है। उनसे मिली पोस्टें मिलीं लेकिन कभी जवाब नहीं मिला, उम्मीद है कि यह दूसरों की भी मदद करेगा।इसे पढ़ने के बिना डब्ल्यूसीएफ सेवा से स्ट्रीम को कैसे रोकें?

मेरे पास WCF सेवा है जो किसी ऑब्जेक्ट को stream के अंदर रखती है। मैं basicHttpBinding का उपयोग स्ट्रीम किए गए स्थानांतरण और एमटीओएम को क्लाइंट को भेजने के लिए करता हूं।

ग्राहक WCF सेवा पर कॉल करता है और प्रतिक्रिया ऑब्जेक्ट प्राप्त करने के तुरंत बाद प्रॉक्सी बंद कर देता है।

अगला, क्लाइंट WCF सेवा से प्राप्त स्ट्रीम को पढ़ता है और इसे स्थानीय डिस्क पर एक फ़ाइल में लिखता है। यह सब ठीक काम करता है।

मेरी समस्या तब होती है जब ग्राहक ऑपरेशन को रद्द करना चाहता है और डब्ल्यूसीएफ सेवा से डेटा डाउनलोड करना बंद कर देता है। यदि मैं स्ट्रीम पर .close() पर कॉल करता हूं, उदाहरण: serverReply.DataStream.Close(); तो यह जारी रखने से पहले डब्लूसीएफ सेवा से पूरी स्ट्रीम को ब्लॉक और पढ़ता है। धारा काफी बड़ी हो सकती है और नेटवर्क हमेशा तेज़ नहीं होता है।

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

मैं समवर्ती कनेक्शन की संख्या में वृद्धि कर सकता हूं, लेकिन यह एक बुरा समाधान होगा क्योंकि यह परेशानी के लिए खुल जाएगा।

उदाहरण के लिए, 20 निरस्त डाउनलोड जो अभी भी इसे फेंकने के लिए डेटा डाउनलोड कर रहे हैं। मुझे ट्रांसफर स्टॉप पूरी तरह से करने की जरूरत है।

क्लाइंट पर, स्ट्रीम ऑब्जेक्ट केवल नियमित Stream वर्ग है, इसलिए इसमें केवल बंद विधि है, और कुछ नहीं।

प्रॉक्सी ऑब्जेक्ट पर .close() या .abort() पर कॉल करने से मदद नहीं मिलती है, न ही .dispose() या किसी अन्य विधि का उपयोग करके इसे नष्ट कर देता है। सर्वर की तरफ, मैं OperationContext.OperationCompleted ईवेंट को संभालता हूं, लेकिन इसे तब तक नहीं निकाल दिया जाता है जब तक कि stream के डेटा को अंत तक पढ़ा नहीं जाता है।

तो सवाल यह है कि, मैं पूरी तरह से इसे पढ़ने के बिना स्ट्रीम को बंद/निरस्त कैसे करूं?

+0

इस के साथ कोई भाग्य? – Schultz9999

+0

वास्तव में बड़ी फ़ाइलों को भेजने के दौरान एक ही समस्या का सामना करना पड़ रहा है ... ऐसा लगता है कि वास्तव में कुछ स्पष्ट होना चाहिए। शायद एक कामकाज के रूप में chunking लागू करने के लिए जा रहा हूँ। –

उत्तर

0

क्या आपने binding.MaxBufferSize के साथ खेलने की कोशिश की है?

<bindings> 
    <wsHttpBinding> 
    <binding name="default" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" 
      closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" > 
     <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" 
        maxDepth="64" maxStringContentLength="2147483647" /> 
    </binding> 

    </wsHttpBinding> 
</bindings> 

मैं anf बफर लंबाई समय समाप्ति कम होगा और निरस्त करने के लिए प्रयास करें या बंद करो और देखो क्या होता है:
आप अपने app.config फ़ाइल सेटिंग्स, उदा, के साथ प्रयोग करना कोशिश की है।

+1

मैंने कोशिश की लेकिन यह मदद नहीं करता है। एक बार जब सर्वर स्ट्रीम भेजना शुरू कर देता है तो यह तब तक नहीं रुकता जब तक कि यह ग्राहक द्वारा प्राप्त नहीं होता है। प्रॉक्सी बंद करना कुछ भी नहीं करता है। ऐसा लगता है कि संचार को रोकने के लिए कोई स्पष्ट तरीका नहीं है। जब ग्राहक स्ट्रीम को पढ़ना बंद कर देता है, तो मैं सर्वर पर वापस जाने के लिए टीसीपी विंडो शून्य देख सकता हूं। और सर्वर समय-समय पर एक विंडो शून्य जांच भेजता है यह देखने के लिए कि क्लाइंट फिर से पढ़ने के लिए तैयार है या नहीं। और निश्चित रूप से ग्राहक फिर से खिड़की शून्य भेजता है। यह तब तक चल रहा है जब तक कि प्रक्रिया की मौत न हो जाए। – Yev

+0

क्या आपने केवल HttpClient क्लास का उपयोग करके स्ट्रीम पढ़ने का प्रयास किया है, और यह देखकर कि क्या आप स्ट्रीम बंद कर सकते हैं? –

+0

डब्ल्यूसीएफ सेवा को कॉल किए बिना मैं ऐसा कैसे करूं? मैंने कुछ और शोध किया है और ऐसा लगता है कि क्लाइंट पक्ष से स्ट्रीम को बंद करने का कोई तरीका नहीं है। मैंने एक अलग दृष्टिकोण की कोशिश की। मैंने एक और सेवा, एक नियंत्रण सेवा बनाई, और वहां से स्ट्रीम को बंद करने की कोशिश की (सर्वर पक्ष)। लेकिन कोई भाग्य नहीं है। कुछ बस काम नहीं करता है, यह बंद या निपटान नहीं करता है। – Yev

1

जांच के बाद मुझे पता चला कि डब्लूसीएफ क्लाइंट स्ट्रीम से स्ट्रीमिंग को तब तक पढ़ेगा जब तक कि बंद टाइमटाइम न हो जाए, तो यह कनेक्शन को रोक देगा। आप समस्या को कम करने के लिए क्लाइंट पर क्लोजटाइमआउट कम कर सकते हैं।

नोट: आपको उस कोड को लपेटना चाहिए जो स्ट्रीम/डिस्क ब्लॉक में स्ट्रीम को डिस्पोजेक्ट करता है। स्ट्रीम। डिस्प्ले() विधि टाइमआउट एक्सेप्शन फेंक देगी जो not throwing exceptions in Dispose method के दिशानिर्देश को तोड़ देती है।

0

मुझे लगता है कि आप केवल बंद होने के बाद बफर प्राप्त कर रहे हैं। आपको maxBufferSize को कम मान पर सेट करना चाहिए।

आप अपनी स्ट्रीम को लपेटकर और पढ़ने को ओवरराइड करके सर्वर पर पढ़ने वाले डेटा की मात्रा को सीमित करना भी चाह सकते हैं। यदि आपके पास कम बैंडविड्थ क्लाइंट है और वास्तव में पढ़ने वाली राशि से मेल खाने के लिए रीड विधि से संबंधित गणना वापस करें तो छोटे भाग का उपयोग करें। यह बफर की भरने दर को प्रतिबंधित करेगा।

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

यदि आपको अभी भी समस्याएं आती हैं तो मेरा सुझाव है कि आप अपने ओवरराइड स्ट्रीम पर रीड विधि के समय को ट्रैक करें। यदि currentReadtime - lastReadTime> x है तो आप इसके बजाय बंद करें और अपवाद फेंक सकते हैं। यह निश्चित रूप से इसे मार देगा।

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