2013-09-05 6 views
6

मेरे अपने वेब सर्वर सॉफ्टवेयर में, मैं सर्वर है कि निम्न स्टैक ट्रेस शामिल पर ईवेंट व्यूअर में प्रविष्टियों हो रही है:.NET थ्रेडिंग/टीसीपी कनेक्शन स्वीकार करने में NullReferenceException का कारण क्या होता है?

Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.ArgumentNullException 
Stack: 
    at System.Net.FixedSizeReader.ReadCallback(System.IAsyncResult) 
    at System.Net.LazyAsyncResult.Complete(IntPtr) 
    at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
    at System.Net.ContextAwareResult.Complete(IntPtr) 
    at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*) 
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*) 

जरूरत नहीं कहने के लिए, इस प्रक्रिया है, जिसका अर्थ सर्वर नीचे चला जाता है दुर्घटनाओं।

चूंकि कोई भी स्टैकट्रैक मेरा कोड नहीं बताता है, इसलिए मैं काफी परेशान हूं। क्या यह .NET में एक बग है? यदि हां, तो क्या कोई ज्ञात कामकाज है? या क्या इस विशेष अपवाद के लिए एक ज्ञात कारण है?

स्टैकट्रैस में उल्लिखित CompletionPortCallback नाम मुझे विश्वास दिलाता है कि ऐसा तब होता है जब सर्वर आने वाले टीसीपी कनेक्शन को स्वीकार करने का प्रयास करता है, इसलिए मैं नीचे के लिए प्रासंगिक कोड शामिल करने जा रहा हूं। बेशक, अगर आपको लगता है कि समस्या कहीं और है तो मुझे अन्य कोड शामिल करने में खुशी होगी।

BeginAccept करने के लिए कॉल इस तरह दिखता है:

यहाँ, _listeningSocket प्रकार System.Net.Sockets.Socket की है।

acceptSocket विधि नीचे दिखाया गया है। मैं यह मानने जा रहा हूं कि टिप्पणियां कोड को पर्याप्त रूप से समझाती हैं; यदि नहीं, तो मुझे एक टिप्पणी में स्पष्ट करने में खुशी हुई। चूंकि यह कोड लाइव सर्वर पर रिलीज मोड में चलता है, #if DEBUG निश्चित रूप से गलत होगा।

private void acceptSocket(IAsyncResult result) 
{ 
#if DEBUG 
    // Workaround for bug in .NET 4.0 and 4.5: 
    // https://connect.microsoft.com/VisualStudio/feedback/details/535917 
    new Thread(() => 
#endif 
    { 
     // Ensure that this callback is really due to a new connection (might be due to listening socket closure) 
     if (!IsListening) 
      return; 

     // Get the socket 
     Socket socket = null; 
     try { socket = _listeningSocket.EndAccept(result); } 
     catch (SocketException) { } // can happen if the remote party has closed the socket while it was waiting for us to accept 
     catch (ObjectDisposedException) { } 
     catch (NullReferenceException) { if (_listeningSocket != null) throw; } // can happen if StopListening is called at precisely the "wrong" time 

     // Schedule the next socket accept 
     if (_listeningSocket != null) 
      try { _listeningSocket.BeginAccept(acceptSocket, null); } 
      catch (NullReferenceException) { if (_listeningSocket != null) throw; } // can happen if StopListening is called at precisely the "wrong" time 

     // Handle this connection 
     if (socket != null) 
      HandleConnection(socket); 
    } 
#if DEBUG 
    ).Start(); 
#endif 
} 
+0

जहां तक ​​मुझे पता है कि आपको '_listeningSocket' को 'startAccept()' कॉल में शून्य के बजाय कॉल करना होगा:' _listeningSocket.BeginAccept (acceptSocket, _listeningSocket); 'दस्तावेज़ और उदाहरण देखें। यही कारण है कि आप ArgumentNull अपवाद प्राप्त किया। –

+0

यह स्पष्ट रूप से .NET ढांचे में एक बग है। यदि आपने एपीआई को msiused किया था तो त्रुटि आईओ कॉलबैक पर बीसीएल के आंतों में गहराई से नहीं होती थी। सवाल यह है कि इसके आसपास कैसे काम करना है। – usr

उत्तर

-1

मुझे लगता है कि यह अपवाद फेंक दिया गया है क्योंकि आप दूसरे पैरामीटर के रूप में एक शून्य संदर्भ पास करते हैं।

MSDN Socket.BeginAccept प्रलेखन (http://msdn.microsoft.com/de-de/library/5bb431f9.aspx) से:

आप एक कॉलबैक विधि है कि AsyncCallback प्रतिनिधि को लागू करता है बना सकते हैं और BeginAccept विधि के लिए इसका नाम से गुजरना होगा। ऐसा करने के लिए, कम से कम, आपको सुनवाई सॉकेट ऑब्जेक्ट को प्रारंभ करने के लिए राज्य पैरामीटर के माध्यम से स्वीकार करना होगा। यदि आपकी कॉलबैक को अधिक जानकारी चाहिए, तो आप सॉकेट और अन्य आवश्यक जानकारी रखने के लिए एक छोटी कक्षा बना सकते हैं। राज्य पैरामीटर के माध्यम से BeginAccept विधि में इस वर्ग का एक उदाहरण पास करें।

+0

यह नहीं है। यह * राज्य * पैरामीटर पर बिल्कुल परवाह नहीं करता है। यह सिर्फ 'IAsyncResult' ऑब्जेक्ट में इसे अनलर्टर करता है जहां आप इसे कॉलबैक में पुनर्प्राप्त कर सकते हैं। यह सिर्फ 'शून्य' हो सकता है ठीक है और यह हमेशा मेरे लिए काम करता है। – Timwi

4

उत्तर उतना आसान है जितना निराशाजनक है।

ऐसा लगता है कि वास्तव में ArgumentNullException मेरे अपने कोड है, जो async कॉल करने के लिए कॉलबैक में मार डाला और स्टैक ट्रेस में किया जाना चाहिए था द्वारा फेंका गया था। मैंने स्टैक ट्रेस पर बहुत भरोसा किया; तथ्य यह है कि यह स्टैक ट्रेस में नहीं दिखाया गया था, मुझे लंबे समय तक गलत ट्रैक पर ले गया।

सी # डेवलपर्स के रूप में पता है, throw; कथन (throw e; नहीं) अपवाद स्टैक ट्रेस को अनचाहे रखना है। System.Net.FixedSizeReader.ReadCallback ऐसे throw; कथन के माध्यम से अपवाद को पकड़ता है और फिर से हटा देता है, फिर भी ईवेंट व्यूअर में दिखाए गए स्टैक ट्रेस को छोटा कर दिया गया। मैं केवल यह अनुमान लगा सकता हूं कि यह सीएलआर या इवेंट व्यूअर में एक बग है या दोनों के बीच कुछ बातचीत है, जिससे throw; से केवल स्टैक ट्रेस का हिस्सा दिखाया जा सकता है।

जब मैंने एक सेवा के बजाय कंसोल पर सॉफ़्टवेयर चलाया, जिसे मैंने बहुत जल्द सोचा था, अपवाद का पूरा स्टैक ट्रेस कंसोल पर दिखाया गया था, यह दर्शाता है कि अपवाद का असली कारण मेरा था कोड।

+0

अपने स्वयं के प्रश्न का उत्तर देने के लिए धन्यवाद, आपका सुझाव है कि स्टैकट्रैक को छोटा कर दिया गया था और इसे कंसोल के रूप में चलाने के लिए मुझे बहुत मदद मिली। मेरे मामले में मैं अपने वेबएक्सप्शन की अपेक्षा कर रहा था। प्रतिक्रिया भरने के लिए जहां यह नहीं था -> nullreference -> बिना किसी त्रुटि के पानी से मेरी nservicebus सेवा blew –

0

https://connect.microsoft.com/VisualStudio/feedback/details/535917 और मेरे अपने अनुभव के आधार पर, यह संभवतः किसी अन्य पुराने मुद्दे से एक नॉक-अप अपवाद है।

वैश्विक अपवाद हैंडलर जोड़ने का प्रयास करें और & डिस्क पर सभी अपवादों को फ्लश करें, फिर असली कारण खोजने के लिए क्रैश के बाद लॉग फ़ाइल देखें।

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