C#聊天应用程序在代码执行时冻结
因此,我一直在用c#开发聊天应用程序,作为一个windows窗体应用程序,当接收数据的代码必须执行时,程序冻结 请任何人帮帮我,找出这有什么问题。作为控制台应用程序,它可以工作C#聊天应用程序在代码执行时冻结,c#,chat,C#,Chat,因此,我一直在用c#开发聊天应用程序,作为一个windows窗体应用程序,当接收数据的代码必须执行时,程序冻结 请任何人帮帮我,找出这有什么问题。作为控制台应用程序,它可以工作 UdpClient udpClient = new UdpClient(Convert.ToInt32(textPort.Text)); IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); By
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();
您的程序被冻结,因为UdpClient类的Receive(…)方法被阻塞 也就是说,它将在该执行点停止,并且不允许它所在的线程/进程继续,直到它接收到一个单个UDP数据包。这包括UI,除非您将其放在单独的线程或异步通信模型中 如果要异步处理通信 下面是一些示例代码(最初,我使用的是此代码。但是,它缺少UdpState的定义。经过一番努力,我发现您必须创建它来传递自己的状态,以便异步模型能够按预期工作。该示例已在VS2008、.Net 3.5中更新和编译):
这有用吗?您的程序被冻结,因为UdpClient类的Receive(…)方法被阻塞 也就是说,它将在该执行点停止,并且不允许它所在的线程/进程继续,直到它接收到一个单个UDP数据包。这包括UI,除非您将其放在单独的线程或异步通信模型中 如果要异步处理通信 下面是一些示例代码(最初,我使用的是此代码。但是,它缺少UdpState的定义。经过一番努力,我发现您必须创建它来传递自己的状态,以便异步模型能够按预期工作。该示例已在VS2008、.Net 3.5中更新和编译):
这有用吗?您应该研究线程是如何工作的。 在windows窗体中,您可以使用 在msdn上,您甚至可以找到一个可用的示例代码。
PS:确保不要在DoWork事件中直接调用UI控件(它在另一个线程上运行)。如果确实需要,可以通过每个windows窗体控件中存在的invoke方法调用它。您应该研究线程是如何工作的。 在windows窗体中,您可以使用 在msdn上,您甚至可以找到一个可用的示例代码。
PS:确保不要在DoWork事件中直接调用UI控件(它在另一个线程上运行)。如果确实需要,请通过每个windows窗体控件中存在的invoke方法调用它。如果使用调试器,能否更具体地说明它冻结的位置?如果使用调试器,请在“Byte[]receiveBytes=udpClient.Receive(ref RemoteIpEndPoint);”(似乎是这样)查找如何使用,你能更具体地说明它冻结的位置吗?在“Byte[]receiveBytes=udpClient.Receive(ref RemoteIpEndPoint);”(看起来是这样)查找如何使用;(谢谢)是的,剩下的唯一问题是我不明白如何将begin Receive方法构建到我的代码中。我为你添加了一些示例代码。您必须定义一个回调来接收消息。这可能是UI中将消息添加到列表或仅将其添加到文本框等的方法。它不适用于UdpState。它说找不到UdpState。您必须将UdpState定义为自己的“数据对象”类,该类在回调中通过引用传回。这是一个常见的模型(虽然我已经有一段时间没做了,所以我忘了)。我更新了在VS2008中为我编译的示例。是的,谢谢。剩下的唯一问题是我不知道如何将begin recieve方法构建到我的代码中。我为您添加了一些示例代码。您必须定义一个回调来接收消息。这可能是UI中将消息添加到列表或仅将其添加到文本框等的方法。它不适用于UdpState。它说找不到UdpState。您必须将UdpState定义为自己的“数据对象”类,该类在回调中通过引用传回。这是一个常见的模型(虽然我已经有一段时间没做了,所以我忘了)。我更新了在VS2008中为我编译的示例。
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);
}
}
}