2008-08-28 2 views
39

ठीक है, मेरे पास मेरे कोड से एक अजीब अपवाद है जो मुझे उम्र के लिए परेशान कर रहा है।WSACancelBlockingCall अपवाद

System.Net.Sockets.SocketException: A blocking operation was interrupted by a call to WSACancelBlockingCall 
    at System.Net.Sockets.Socket.Accept() 
    at System.Net.Sockets.TcpListener.AcceptTcpClient() 

MSDN इस पर बहुत उपयोगी नहीं है: http://msdn.microsoft.com/en-us/library/ms741547(VS.85).aspx और मैं भी कि यह कैसे एक समस्या निवारण शुरू करने के लिए पता नहीं है। यह केवल दिन में 4 या 5 बार फेंक दिया जाता है, और हमारे परीक्षण वातावरण में कभी नहीं। केवल उत्पादन साइटों में, और सभी उत्पादन साइटों पर।

मुझे इस अपवाद के बारे में पूछने के लिए बहुत सी पोस्ट मिल गई हैं, लेकिन इसके कारण होने पर कोई वास्तविक निश्चित उत्तर नहीं है, और इसे कैसे संभालना या रोकना है।

कोड एक अलग पृष्ठभूमि धागा में चलता है, विधि शुरू होता है:

public virtual void Startup() 
    { 
    TcpListener serverSocket= new TcpListener(new IPEndPoint(bindAddress, port));  
     serverSocket.Start(); 

तो मैं एक पाश एक अलग थ्रेड पूल में नौकरियों के रूप में सभी नए कनेक्शन डाल चलाते हैं। यह एप्लिकेशन वास्तुकला की वजह से और अधिक जटिल हो जाता है, लेकिन मूल रूप से:

while ((socket = serverSocket.AcceptTcpClient()) !=null) //Funny exception here 
    { 
     connectionHandler = new ConnectionHandler(socket, mappingStrategy); 
     pool.AddJob(connectionHandler); 
    } 
    } 

वहाँ से, pool अपने आप धागे कि उसके अपने सूत्र में हर काम का ख्याल रखना है, अलग से है।

मेरी समझ यह है कि AcceptTcpClient() एक अवरुद्ध कॉल है, और किसी भी तरह winsock थ्रेड को अवरुद्ध करने और निष्पादन जारी रखने के लिए कह रहा है .. लेकिन क्यों? और मुझे क्या करना चाहिए? बस अपवाद पकड़ो और इसे अनदेखा करें?


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

वैकल्पिक रूप से, क्या यह केवल आईआईएस सर्वर मेरे आवेदन को बंद कर सकता है, और इस प्रकार मेरे सभी पृष्ठभूमि धागे और अवरुद्ध तरीकों को रद्द कर सकता है?

उत्तर

35

क्या यह संभव है कि सर्वर सॉकेट किसी अन्य थ्रेड से बंद हो रहा हो? इससे यह अपवाद होगा।

+0

कहें कि यह है। आप इसे किसी अन्य धागे से कैसे बंद करते हैं? क्या सॉकेट को 'अस्थिर' होना चाहिए? –

+1

नहीं, जब तक अन्य धागे में सॉकेट ऑब्जेक्ट का संदर्भ हो, तब तक यह इसे बंद कर सकता है। – TimK

+0

यदि आप ब्लॉक स्थिति में हैं तो आप उसी थ्रेड से सॉकेट को कैसे बंद कर सकते हैं ??? –

4

यह serverSocket.Stop() पर हो सकता है। जिसे मैंने Dispose कहा था, जिसे मैंने बुलाया था।

यहाँ कैसे सुन थ्रेड के लिए मेरी अपवाद संचालन की तरह दिखाई देता है:

try 
{ 
    //... 
} 
catch (SocketException socketEx) 
{  
    if (_disposed) 
     ar.SetAsCompleted(null, false); //exception because listener stopped (disposed), ignore exception 
    else 
     ar.SetAsCompleted(socketEx, false); 
} 

अब क्या हुआ था, हर बार अपवाद से पहले _disposed सही पर सेट किया गया था घटित होता। तो मेरे लिए समाधान सब कुछ धागा सुरक्षित बनाना था।

3

वही यहाँ! लेकिन मुझे पता चला कि 'सर्वर-साइड' पर रिसीव बफर ग्राहकों से बाढ़ आ गई थी!

(मेरे मामले में एक आरएफआईडी-स्कैनर्स, जो जब तक अगले TagCode आता भेजने TagCode स्पैमिंग रखा, स्टॉप की बजाय गुच्छा) यह ReceiveBuffers उठाते हैं और स्कैनर को पुन: कॉन्फ़िगर करने के लिए मदद ...

5

यह मेरा उदाहरण समाधान से बचने के लिए WSAcancelblablabla है: वैश्विक रूप में अपने धागा परिभाषित करें तो आप इस तरह आह्वान विधि का उपयोग कर सकते हैं:

private void closinginvoker(string dummy) 
    { 
     if (InvokeRequired) 
     { 
      this.Invoke(new Action<string>(closinginvoker), new object[] { dummy }); 
      return; 
     } 
     t_listen.Abort(); 
     client_flag = true; 
     c_idle.Close(); 
     listener1.Stop(); 
    } 

आप इसे आह्वान के बाद, धागा पहले तो हमेशा के लिए लूप झंडा तो बंद यह आगे इंतजार कर रहा है (यदि आपके पास है), तो tcpclient बंद करें तो श्रोता को रोकें।

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