2011-08-24 19 views
6

मैं वर्तमान में एक प्रबंधित सी # नेटवर्क लाइब्रेरी का परीक्षण कर रहा हूं जिसे मैंने लिखा है और मैं कभी-कभी समस्या के खिलाफ आया हूं। यह समस्या नेटवर्क भेजने के लिए एक बहुत ही सुसंगत (हमेशा 30ms के भीतर) 5000ms ब्लॉक के रूप में प्रकट होती है, जो सभी प्रेषण कार्यों में से 1% के लिए होती है। यह परीक्षण परीक्षण में है, सभी स्थानीय रूप से चल रहे हैं, प्रत्येक बार सटीक उसी पैकेट आकार (2 एमबी) का उपयोग करते हुए। ग्राहक छोर पर मैं लगातार एक जुड़ा networkstream के लिए निम्न लिखें:नेटवर्कस्ट्रीम। राइट() ब्लॉकिंग समस्या

tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length); 
tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length); 

और सर्वर अंत पर मैं एक अतुल्यकालिक डेटा के लिए इंतज़ार कर पढ़ का उपयोग करें। एक बार डेटा प्रकट होने पर मैं tcpClientNetworkStream.Data पर उपलब्ध होने पर एक समय लूप का उपयोग करता हूं जब तक कि सभी डेटा प्राप्त नहीं हो जाता है।

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

मार्क जोड़ने के लिए

संपादित करें: एक हैक जो समस्या का समाधान करने के लिए लगता है निम्नलिखित है (हालांकि वहाँ BlockCopy की वजह से मारा एक संबद्ध प्रदर्शन है):

byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length]; 
Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length); 
Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length); 
tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length); 

add2 को संपादित करें : मैंने दोनों के बीच थ्रेड सिग्नल के साथ दो एसिंक्रोनस लिखने का उपयोग करके समस्या का पुन: उत्पन्न किया है। फिलहाल मेरे पास एकमात्र समाधान है जो उपरोक्त संपादन में एकल लेखन ऑपरेशन है।

add3 में संपादित करें: ठीक है, एक और संभावित फिक्स निम्नानुसार है। मुझे अभी भी यह जानने में दिलचस्पी है कि लगातार लिखने के तरीके में कभी-कभी 'ब्लॉक' क्यों होता है।

BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream); 
sendStream.Write(bytesToSend, 0, bytesToSend.Length); 
sendStream.Write(packet.PacketData, 0, packet.PacketData.Length); 
sendStream.Flush(); 

add4 को संपादित करें: के बाद आगे व्यापक में समाधान का परीक्षण 'संपादन add3 करने के लिए' समस्या का समाधान नहीं है, यह सिर्फ घटना के बारे में 0.1% करने के लिए कम कर देता है के लिए भेजता है। बहुत बेहतर लेकिन हल से दूर। मैं पॉलिफ़ द्वारा सुझाए गए अनुसार, यह देखने के लिए आगे क्या एक ब्लॉकिंग रीड के साथ एसिंक्रोनस रीडिंग को बदल देगा।

+0

अधिक कोड पोस्ट करें, जैसे डेटाबेट्स कहां से आ रहे हैं? क्या यह कहीं कहीं buffered है? – EKS

+0

मैं एक पैकेट ऑब्जेक्ट को SendPacket() विधि में पास करता हूं जिसमें उपरोक्त NetworkStream.Write() विधियां हैं। एक बार यह पैकेट ऑब्जेक्ट SendPacket() के बाहर बनाया गया है, इसमें 'हेडरबाइट्स' और 'डेटाबाइट्स' दोनों के लिए बाइट एरे शामिल हैं। – MarcF

+0

मुझे यह जानकर उत्सुकता है कि अगर आप सर्वर पर सिंक्रोनस (अवरुद्ध) पढ़ते हैं तो समस्या बनी रहती है या नहीं। – PaulF

उत्तर

2

ठीक है, इस प्रश्न का कोई विशिष्ट जवाब नहीं है, इसलिए मैं थोड़ा निष्कर्ष प्रदान करने के लिए अपनी पूरी कोशिश करूंगा। मेरा सबसे अच्छा अनुमान यह है कि यह समस्या मूल रूप से इसलिए हुई थी क्योंकि मैं इसे साफ़ करने से पहले टीसीपी बफर को तेज़ी से भर रहा था। यदि बफर भर जाता है तो अधिक डेटा जोड़ने का प्रयास करने से पहले कुछ अज्ञात प्रतीक्षा समय होता है। एक ही मशीन के भीतर डेटा भेजने और प्राप्त करने पर यह समस्या शायद सबसे स्पष्ट होगी। यह याद रखना महत्वपूर्ण है कि .NET में डिफ़ॉल्ट रीड बफर आकार केवल 8192 बाइट है, इसलिए यदि अधिक बड़े हिस्सों में लिखना है, तो शायद इस पढ़ने वाले बफर आकार को 512000 बाइट्स जैसे बड़े आकार में बढ़ाने पर विचार करें। हालांकि यह बड़े ऑब्जेक्ट ढेर आदि के कारण अन्य मुद्दों का कारण बनता है लेकिन यह संभावित रूप से एक अलग प्रश्न पर चर्चा करता है।

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