2011-10-24 13 views
5

Beni bu istisna kurtulmak için yardımcı olabilir misiniz:nasıl SocketException durdururum: fırlamaya karşı "Engelleyici bir işlem WSACancelBlockingCall çağrısıyla kesildi"?

System.Net.Sockets.SocketException:

  1. "Bir engelleme işlemi WSACancelBlockingCall çağrısıyla tarafından kesintiye oldu" Ne Aşağıdaki kod şunları yapar: sunucuya UDP iletisini gönderir ve yanıtı alır (NAK veya ACK)

  2. Özel durum atan kod: m_receiveBytes = m_receiver.Receive(ref m_from);

Kodu:

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(); 
     } 
    } 
} 

cevap

4

Ben kodunuzu doğru okuyorsam, bir UDP mesaj almak için bir iş parçacığı başlıyoruz. İletiyi alırsa, bir olay ayarlar. Ana iş parçacığı iş parçacığı başlatır ve olayın ayarlanması için beş saniyeye kadar bekler. Olay bu süre içinde ayarlanmazsa, ana iş parçacığı parçacığı bekliyor alıcıyı yok eder. kesinlikle bir istisna olacak

. Eğer istisna ortadan kaldırmak için beklerseniz

değiştirmek senin ThreadProc

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

Sana bir finally bölümünde m_mre.Set() çağrıyı içermez öneririm. Ana iş parçacığı, beklemenin tamamlanmasının ardından bir zaman aşımı olup olmadığına bakılmaksızın etkinlikle ilgili Reset numaralı telefonu arar.

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 

Bunun yerine, bu gibi görünmek için ana iş parçacığı kodunu değiştirmek: iplik nihayet Set çağırırsa bir zaman aşımı oluşursa şu olur, çünkü etkinliğin devlet kurulacaktır

gerçekten bunu yapmanın bir iş parçacığı kadar dönmeye gerek yok, söylediğin. Bunun yerine, UdpClient'un zaman uyumsuz yeteneklerini kullanabilirsiniz. gibi bir şey:

Gerçekten takdir
// 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

i önerinizi deneyeceğim ve ben aşağıya mantığı deneyin ama maalesef hala aynı hata var size geribildirim – user852194

+0

Merhaba Jim vereceğiz. – user852194

+0

@ user852194: Tam olarak aldığınız istisna nedir? 'Catch' aslında istisnayı yakalıyor mu? –

İlgili konular