2013-12-22 39 views
0

因此,我一直在使用C#作爲Windows窗體應用程序中的聊天應用程序,並且在接收數據的代碼必須執行時,程序會凍結。C#聊天應用程序執行代碼時會凍結

任何人都可以幫助我,找出最新的錯誤。作爲一個控制檯應用程序,

UdpClient udpClient = new UdpClient(Convert.ToInt32(textPort.Text)); 

      IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); 

      Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); 
      string returnData = Encoding.ASCII.GetString(receiveBytes); 

      textMsg.Text = returnData.ToString(); 
+0

如果您使用的是調試器,您可以更具體地瞭解它在哪裏凍結? – FuzzyBunnySlippers

+0

查找如何使用[BeginReceive](http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v = vs.110).aspx) – rene

+0

at「Byte [ ] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);「 (它似乎是這樣) – user3002135

回答

5

由於UdpClient類的Receive(...)方法被阻塞,所以程序被凍結。

也就是說,它將在該執行點停止並且不允許它所在的線程/進程繼續,直到它收到一個單個 UDP數據包。這包括UI,除非你把它放在一個單獨的線程或我們的異步通信模型中。

如果要異步處理通訊,請撥打check out the BeginReceive(...) method。這是一些示例代碼(原來,我使用的代碼是straight from Microsoft。但是,它缺少UdpState的定義。在咬牙切齒之後,我發現你必須創建它來傳遞你自己的狀態。異步模式將按預期工作。示例已更新並編譯在VS2008,.Net 3.5中):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
    class UdpState 
    { 
     public IPEndPoint e = null; 
     public UdpClient u = null; 
    } 

    class Program 
    { 
     public static bool messageReceived = false; 

     public static void ReceiveCallback(IAsyncResult ar) 
     { 
      UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u; 
      IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e; 

      Byte[] receiveBytes = u.EndReceive(ar, ref e); 
      string receiveString = Encoding.ASCII.GetString(receiveBytes); 

      Console.WriteLine("Received: {0}", receiveString); 
      messageReceived = true; 
     } 

     public static void ReceiveMessages(int listenPort) 
     { 
      // Receive a message and write it to the console. 
      IPEndPoint e = new IPEndPoint(IPAddress.Any, listenPort); 
      UdpClient u = new UdpClient(e); 

      UdpState s = new UdpState(); 
      s.e = e; 
      s.u = u; 

      Console.WriteLine("listening for messages"); 
      u.BeginReceive(new AsyncCallback(ReceiveCallback), s); 

      // Do some work while we wait for a message. For this example, 
      // we'll just sleep 
      while (!messageReceived) 
      { 
       Thread.Sleep(100); 
      } 
     } 

     static void Main(string[] args) 
     { 
      ReceiveMessages(10000); 
     } 
    } 
} 

對您有幫助嗎?

+0

是的謝謝剩下的唯一問題是我不明白如何將開始接收方法內置到我的代碼中。 – user3002135

+0

我爲你添加了一些示例代碼。你必須定義一個回調來接收消息。這可能是您的用戶界面中的一種方法,它將消息添加到列表中或僅將其添加到文本框等。 – FuzzyBunnySlippers

+0

它不適用於UdpState。它說它找不到。 – user3002135

0

您應該研究線程是如何工作的。 在Windows窗體中,你可以使用BackgroundWorker

在msdn上,你甚至可以找到一個有效的示例代碼。 PS:確保不要直接在DoWork事件中調用UI控件(它在另一個線程上運行)。如果您真的需要,可以通過每個窗體窗體控件中存在的Invoke方法調用它。