Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#聊天应用程序在代码执行时冻结_C#_Chat - Fatal编程技术网

C#聊天应用程序在代码执行时冻结

C#聊天应用程序在代码执行时冻结,c#,chat,C#,Chat,因此,我一直在用c#开发聊天应用程序,作为一个windows窗体应用程序,当接收数据的代码必须执行时,程序冻结 请任何人帮帮我,找出这有什么问题。作为控制台应用程序,它可以工作 UdpClient udpClient = new UdpClient(Convert.ToInt32(textPort.Text)); IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); By

因此,我一直在用c#开发聊天应用程序,作为一个windows窗体应用程序,当接收数据的代码必须执行时,程序冻结

请任何人帮帮我,找出这有什么问题。作为控制台应用程序,它可以工作

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