关于while(true)一用即挂死的问题

youisbest7777 2014-09-29 08:56:17
作一个socket接收服务器端的程序,结果网上看到示例用while(true)但在应用窗口程序与window服务程序中一运行即卡死挂掉,而在控制台程序项目中就可以正常运行,相关代码如下:
应用窗口程序:(一运行即挂了,不知什么原因)
private static byte[] result = new byte[1024];
public struct MyVariable
{
public Socket client;
public void set()
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
}
private static MyVariable Rcconnect = new MyVariable();
// socket端口号常量.
private static IPAddress ipAddress = IPAddress.Parse("127.0.0.1");//ipHostInfo.AddressList[0];
private const int port = 6008;
private void StartClient()
{
try
{
Rcconnect.set();
Rcconnect.client.Connect(new IPEndPoint(ipAddress, port)); //配置服务器IP与端口
if (Rcconnect.client.Connected)
listBox1.Items.Add(DateTime.Now + " Connect>" + "与FCS服务器连接成功");else
listBox1.Items.Add(DateTime.Now + " Connect>" + "与FCS服务器连接失败");
}
catch(Exception e) {
listBox1.Items.Add(DateTime.Now + " Connect>" + e.Message + "=与FCS服务器连接失败");

}
}
private void button1_Click(object sender, EventArgs e)
{
StartClient();
//接收信息
while (true)
{
int receiveLength = Rcconnect.client.Receive(result);
listBox1.Items.Add(DateTime.Now + " RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
}
}

控制台程序中应用while(true)完全没有问题,代码如下:
private static byte[] result = new byte[1024];
static void Main(string[] args)
{ //设定服务器IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 6008)); //配置服务器IP与端口
Console.WriteLine("连接服务器成功");
}
catch
{
Console.WriteLine("连接服务器失败,请按回车键退出!");
return;
}
//通过clientSocket接收数据
while (true)
{
int receiveLength = clientSocket.Receive(result);
Console.WriteLine("接收服务器消息:{0}", Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
}
}
...全文
1769 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
於黾 2014-09-30
  • 打赏
  • 举报
回复
死循环慎用 要么不用,要么放到线程里去用,永远不要在主线程里while(true)
tcmakebest 2014-09-30
  • 打赏
  • 举报
回复
while(true)这张弓不能缺了break这根弦,总原地转圈当然挂了.
sunny906 2014-09-30
  • 打赏
  • 举报
回复
引用 11 楼 cgcgyv 的回复:
[quote=引用 7 楼 sunny906 的回复:] 不用加Sleep,因为Receive会阻塞线程,只需要把while(true)放到多线程里就可以了

            Task.Factory.StartNew(new Action(() =>
                {
                    while (true)
                    {
                        int receiveLength = Rcconnect.client.Receive(result);
                        listBox1.Items.Add(DateTime.Now + "  RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
                    }
                }));
这样不行,在线程中,控件不能直接调用,会报错的。改成这样
Task.Factory.StartNew(new Action(() =>
{
    while (true)
    {
        int receiveLength = Rcconnect.client.Receive(result);
        listBox1.Invoke((Action)(() =>
        {
            listBox1.Items.Add(DateTime.Now + "  RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
        }));
    }
}));
[/quote] 恩,失误,写漏了,没注意到有控件对象
大头说 2014-09-30
  • 打赏
  • 举报
回复
引用 7 楼 sunny906 的回复:
不用加Sleep,因为Receive会阻塞线程,只需要把while(true)放到多线程里就可以了

            Task.Factory.StartNew(new Action(() =>
                {
                    while (true)
                    {
                        int receiveLength = Rcconnect.client.Receive(result);
                        listBox1.Items.Add(DateTime.Now + "  RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
                    }
                }));
这样不行,在线程中,控件不能直接调用,会报错的。改成这样
Task.Factory.StartNew(new Action(() =>
{
    while (true)
    {
        int receiveLength = Rcconnect.client.Receive(result);
        listBox1.Invoke((Action)(() =>
        {
            listBox1.Items.Add(DateTime.Now + "  RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
        }));
    }
}));
老李家的小二 2014-09-30
  • 打赏
  • 举报
回复
上面说的很对,while (true) 里面最好有个break;比如接收服务端数据超过规定时长,则推出;否则,真的是死里面啦。
於黾 2014-09-30
  • 打赏
  • 举报
回复
其实winform也没有死掉,逻辑还在正常执行,只不过界面卡死了而已 你用控制台程序,也是逻辑在执行,但是不会再响应输入了
黑子大哥 2014-09-30
  • 打赏
  • 举报
回复
引用 楼主 youisbest7777 的回复:
作一个socket接收服务器端的程序,结果网上看到示例用while(true)但在应用窗口程序与window服务程序中一运行即卡死挂掉,而在控制台程序项目中就可以正常运行,相关代码如下: 应用窗口程序:(一运行即挂了,不知什么原因) private void button1_Click(object sender, EventArgs e) { StartClient(); //接收信息 while (true) { int receiveLength = Rcconnect.client.Receive(result); listBox1.Items.Add(DateTime.Now + " RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength)); } } 控制台程序中应用while(true)完全没有问题,代码如下: private static byte[] result = new byte[1024]; static void Main(string[] args) { //设定服务器IP地址 IPAddress ip = IPAddress.Parse("127.0.0.1"); Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { clientSocket.Connect(new IPEndPoint(ip, 6008)); //配置服务器IP与端口 Console.WriteLine("连接服务器成功"); } catch { Console.WriteLine("连接服务器失败,请按回车键退出!"); return; } //通过clientSocket接收数据 while (true) { int receiveLength = clientSocket.Receive(result); Console.WriteLine("接收服务器消息:{0}", Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength)); } }
你这很明显啊!!无语 while (true) 这个东西岂能是主线程使用的!!!这不是控制台啊亲!!
stormem 2014-09-30
  • 打赏
  • 举报
回复
你 要启用一个线程。
mlqxj35674 2014-09-29
  • 打赏
  • 举报
回复
不死还能怎么的,起码也得给个退出的机会啊
sunny906 2014-09-29
  • 打赏
  • 举报
回复
不用加Sleep,因为Receive会阻塞线程,只需要把while(true)放到多线程里就可以了

            Task.Factory.StartNew(new Action(() =>
                {
                    while (true)
                    {
                        int receiveLength = Rcconnect.client.Receive(result);
                        listBox1.Items.Add(DateTime.Now + "  RecConext>" + Encoding.GetEncoding("GB2312").GetString(result, 0, receiveLength));
                    }
                }));
l2999019 2014-09-29
  • 打赏
  • 举报
回复
你这..直接在主线程里while(true) 肯定不行啊..一般就算是要用while(true)..也是会开一个子线程,
xian_wwq 2014-09-29
  • 打赏
  • 举报
回复
引用 2 楼 youisbest7777 的回复:
那要在这里保持不间断的socket长连接性质的信息接收,应当怎样变通处理才好,用过时间控件,没有用
要保持长连接,简单办法是客户端维持心跳 一旦失败,重新连接
zhujiazhi 2014-09-29
  • 打赏
  • 举报
回复
在click方法里面while(true),这个会卡住,不会返回的,所以有问题的, 正常会在click的方法里面新开一个线程,在新的线程里面去while(true)监听
PaulyJiang 2014-09-29
  • 打赏
  • 举报
回复
while(true) 在后面添加一个sleep吧 这样就不会死机了
youisbest7777 2014-09-29
  • 打赏
  • 举报
回复
那要在这里保持不间断的socket长连接性质的信息接收,应当怎样变通处理才好,用过时间控件,没有用
by_封爱 版主 2014-09-29
  • 打赏
  • 举报
回复
http://www.cnblogs.com/chenxizhang/archive/2011/09/10/2172994.html 看看这个吧.. 超级不错的.. while(true)这东西不是很好.相对异步来说... 所以你这代码只能自己玩玩...
  • 打赏
  • 举报
回复
方案1 查看关于线程内容,做个线程处理循环。 方案2 查看异步SOCKET 。
jobscq 2014-09-29
  • 打赏
  • 举报
回复
大家都说的很清楚了,因为Receive是个同步方法,当没收到套接字对应主机的响应时会卡住线程,除了第一次Receive正确接收到消息后,你的线程就被死循环的第二次Receive卡住,后面的循环已经没有任何意义。 而你用控制台,在第一次Receive的时候面临的是控制台的退出,因为程序没执行完成(即线程没退出),所以你此时卡住的是控制台的退出,并未将循环执行下去,因此让你错误的以为控制台是可以执行的。 为什么用控制台的时候,往往都要加一句Console.ReadKey(); 就是为了阻止线程的结束,你这里的死循环起到了这个效果而已

111,093

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧