2011-10-24 10 views
5

आप मुझे इस अपवाद से छुटकारा पाने के लिए मदद कर सकते हैं:मैं सॉकेटएक्सप्शन को कैसे रोकूं: "डब्लूएसएसीसीएनलब्लॉकिंग कॉल को कॉल करके अवरुद्ध करने वाला ऑपरेशन बाधित होने से बाधित था?"

System.Net.Sockets.SocketException:

  1. "एक अवरुद्ध आपरेशन एक कॉल से बाधित WSACancelBlockingCall के लिए गया था" क्या नीचे दिया गया कोड करता है: सर्वर पर यूडीपी संदेश भेजता है और उत्तर (एनएके या एसीके)

  2. कोड जो अपवाद फेंकता है: m_receiveBytes = m_receiver.Receive(ref m_from);

कोड:

public partial class _Default : System.Web.UI.Page 
{ 
    static readonly object lockScheduleIem = new object(); 
    IPAddress m_AddressSend; 
    IPAddress m_AddressRecieve; 
    int m_groupPortSend; 
    int m_groupPortReceive; 
    IPEndPoint m_IPAddressSend; 
    IPEndPoint m_IPAddressReceive; 
    Byte[] m_receiveBytes; 
    Thread m_thread; 
    UdpClient m_receiver; 
    ManualResetEvent m_mre; 
    UdpClient m_sender; 
    IPEndPoint m_from; 

    protected void Page_Init(object sender, EventArgs e) 
    { 
     m_AddressSend = IPAddress.Parse("10.43.60.177"); 
     m_AddressRecieve = IPAddress.Parse("10.43.60.99"); 

     int.TryParse("60200", out m_groupPortSend); 
     int.TryParse("206", out m_groupPortReceive); 

     m_IPAddressSend = new IPEndPoint(m_AddressSend, m_groupPortSend); 
     m_IPAddressReceive = new IPEndPoint(m_AddressRecieve, m_groupPortReceive); 

     m_mre = new ManualResetEvent(false); 
     m_from = new IPEndPoint(IPAddress.Any, 0); 
    } 
    protected void Page_Load(object sender, EventArgs e) 
    { 

    } 

    protected void Button1_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      TimeSpan timeout; 
      timeout = new TimeSpan(0, 0, 0, 0, 5000); 
      m_sender = new UdpClient(); 
      m_receiveBytes = null; 
      m_receiver = new UdpClient(m_IPAddressReceive); 
      m_thread = new Thread(new ThreadStart(ThreadProc)); 
      m_thread.Start(); 
      string str = string.Empty; 
      using (StreamReader sr = new StreamReader(@"C:\UDPmsgArchive\UDPmsg_Of_2011_10_18_13_7_33_968_634545400539687500.xml")) 
       str = sr.ReadToEnd(); 
      byte[] XMLbytes = Encoding.ASCII.GetBytes(str); 
      m_sender.Send(XMLbytes, XMLbytes.Length, m_IPAddressSend); 

      m_mre.WaitOne(timeout, true); 
      m_mre.Reset(); 
      m_receiver.Close(); 

      if (m_receiveBytes != null) 
       Response.Write(Encoding.ASCII.GetString(m_receiveBytes, 0, m_receiveBytes.Length)); 
      else 
       Response.Write("string.Empty"); 
     } 
     catch (Exception ex) 
     { 
      Response.Write(ex.ToString()); 
     } 
    } 

    public void ThreadProc() 
    { 
     try 
     { 
      m_receiveBytes = m_receiver.Receive(ref m_from); // ERROR HERE 
      m_mre.Set(); 
      m_receiver.Close(); 
     } 
     finally 
     { 
      m_mre.Set(); 
     } 
    } 
} 

उत्तर

4

मैं अपने कोड सही पढ़ रहा हूँ, तो आप एक यूडीपी संदेश प्राप्त करने के लिए एक धागा शुरू कर रहे हैं। अगर यह संदेश प्राप्त करता है, तो यह एक घटना सेट करता है। मुख्य धागा धागा शुरू करता है और फिर ईवेंट को सेट करने के लिए पांच सेकंड तक प्रतीक्षा करता है। यदि घटना उस समय के भीतर सेट नहीं है, तो मुख्य धागा रिसीवर को नष्ट कर देता है कि थ्रेड प्रतीक्षा कर रहा है।

यह निश्चित रूप से अपवाद फेंकने जा रहा है।

आप अपवाद को खत्म करने की प्रतीक्षा करते हैं तो संशोधित अपने ThreadProc

try 
{ 
    // do stuff here 
} 
catch (SocketException) // or whatever the exception is that you're getting 
{ 
} 

मैं सुझाव है कि आप एक finally खंड में m_mre.Set() कॉल शामिल नहीं। इंतजार पूरा होने के बाद मुख्य थ्रेड Reset पर कॉल करता है, चाहे कोई टाइमआउट हो या नहीं। धागा कॉल करता है अंत में में Set, घटना की राज्य, अगर समय समाप्त होता है में सेट किया जाएगा निम्न होता है:

if (m_mre.WaitOne(timeout, true)) 
{ 
    // event was set by the thread proc 
    // process the received data 
    // and reset the event 
    m_mre.Reset(); 
} 
else 
{ 
    // A timeout occurred. 
    // Close the receiver 
    m_receiver.Close(); 
} 
:

main thread calls Reset() 
main thread calls Close() on the client 
ThreadProc calls Set() in the finally 

इसके बजाय, इस तरह देखने के लिए अपने मुख्य थ्रेड कोड बदलने

उसने कहा, आपको वास्तव में ऐसा करने के लिए धागे को स्पिन करने की आवश्यकता नहीं है। इसके बजाय, आप UdpClient की एसिंक्रोनस क्षमताओं का उपयोग कर सकते हैं। की तरह कुछ:

// Set timeout on the socket 
m_receiver.Client.ReceiveTimeout = 5000; 
try 
{ 
    IAsyncResult ir = m_receiver.BeginReceive(null, null); 
    m_receivedBytes = m_receiver.EndReceive(ir, m_receiver.Client.RemoteEndPoint); 
    // process received bytes here 
} 
catch (SocketException) 
{ 
    // Timeout or some other error happened. 
} 
+0

सच की सराहना की, मैं अपने सुझाव की कोशिश करेंगे, और मैं आप प्रतिक्रिया – user852194

+0

हाय जिम दूँगा मैं नीचे अपना तर्क की कोशिश लेकिन दुर्भाग्य से अब भी वही त्रुटि की है। – user852194

+0

@ user852194: आपको प्राप्त सटीक अपवाद क्या है? वास्तव में अपवाद को पकड़ने वाला 'पकड़' है? –

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