C#的Winform程序假死

KING_314 2010-08-06 11:48:31
额 我不知道怎么描述这个问题啊 就是运行程序的时候form无法显示出来 ,点击没有反应。根据代码运行,执行第一次可以看到界面,但是循环执行的时候就会无法显示出来。注:做的是TCP/IP端口通信的。本人才疏,那个整了3-4天了,只能进行基本的数据发送与接收。这个还是在加了messageBox的情况下,界面才显示出来。去掉messageBox之后便会出现假死的情况。非常郁闷。。。。

具体接收部分代码如下:(通过监测本机的8000端口,查看是否有连接)

int portNum = 8000;
bool done = false;

TcpListener listener = new TcpListener(portNum);

listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
while (!done)
{
Console.Write("Waiting for connection...");
ReceiveLB.Items.Add("Waiting for connection...");
//TcpClient client = listener.AcceptTcpClient();

Console.WriteLine("Connection accepted.");
ReceiveLB.Items.Add("Connection accepted.");

byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());

byte[] buff=new byte[1000];
try
{
if (client==null)
{
client = listener.AcceptTcpClient();
ns = client.GetStream();
}
//写数据
ns.Write(byteTime, 0, byteTime.Length);
//ReceiveLB为listbox,采用线程的话会报线程中无法调用
ReceiveLB.Items.Add("send:"+System.Text.Encoding.ASCII.GetString(byteTime));
MessageBox.Show(System.Text.Encoding.ASCII.GetString(byteTime));
//读数据
ns.Read(buff, 0, buff.Length);
ReceiveLB.Items.Add("receive:" + System.Text.Encoding.ASCII.GetString(buff));
MessageBox.Show(System.Text.Encoding.ASCII.GetString(buff));
//ns.Close();
//client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

}

client.Close();
listener.Stop();
-----分割线-----

我希望能将接收到得数据保存至数据库,但是现在有个问题是当我长时间不点击messagebox时,会出现若干个重复数据串123456 123456 ......(发送端数据为123456)

额 希望有TCP/IP编程经验的高手指点下 有相关C#的源代码请发qxw88@163.com。谢谢


...全文
902 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
周药师 2010-08-06
  • 打赏
  • 举报
回复
把阻塞的放线程里
dodducs 2010-08-06
  • 打赏
  • 举报
回复
你要明白一个问题,,,,如果你不创建子线程 默认的使用 UI进程的话
那你的界面肯定会阻塞

就好比 高速公路 同一方向有2条路 是为了超车方便
如果只有一条的话 你超得过去车?

主次要搞清楚,,你的UI进程是主 不要把他阻塞
通过子线程去控制逻辑代码

Thread t = new Thread(new ThreadStart(方法名));
t.Start();

这样就可以创建子线程去工作了
johndii 2010-08-06
  • 打赏
  • 举报
回复
没必要用messagebox打印日志不就好了。
这是C#又开源网络组件的,通讯没必要自己写,快速完成业务就好。
foryouwife 2010-08-06
  • 打赏
  • 举报
回复
用线程做。就不会卡死。你这样肯定会卡死的。
sxiaohui8709253 2010-08-06
  • 打赏
  • 举报
回复
可以把MessageBox.Show(System.Text.Encoding.ASCII.GetString(byteTime));
这个要Show的东西 让他在一个TextBox上显示 方法如下
delegate void SetTextBoxTextCallBack(string byteTime); //跨线程操作TextBox控件委托

private void UpdateTextBox1Text(string byteTime)
{
if (this.TextBox1.InvokeRequired)
{
SetTextBoxTextCallBack m_SetTextBoxTextCallBack = new SetTextBoxTextCallBack(UpdateTextBox1Text);
this.BeginInvoke(m_SetTextBoxTextCallBack, new object[] { byteTime});
}
else
{
this.TextBox1.Text += byteTime;
}
}

然后把MessageBox.Show()那里改成UpdateTextBox1Text( byteTime)
wxm3630478 2010-08-06
  • 打赏
  • 举报
回复
TcpListener listener = new TcpListener(portNum);

listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();

用一个方法封装......然后用线程启动 (Thread类)


while (!done) 也循环需要放在一个子线程里
KING_314 2010-08-06
  • 打赏
  • 举报
回复
接这个问题,我需要将接收到的数据保存入数据库,这个也是通过线程来完成么?
KING_314 2010-08-06
  • 打赏
  • 举报
回复

//引用集
using System.Threading;

/***********************************/
private Thread thThreadread;//创建线程,用以侦听端口号,接受信息

/*******************/
///接收按钮
private void ReceiveBTN_Click(object sender, EventArgs e)
{
thThreadread = new Thread(new ThreadStart(TcpTimeServer));
thThreadread.Start();//启动线程
}

///监听端口,进行连接
private void TcpTimeServer()
{
int portNum = 8000;
bool done = false;
TcpListener listener = new TcpListener(portNum);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
while (!done)
{

byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());

byte[] buff=new byte[1000];
try
{
if (client==null)
{
client = listener.AcceptTcpClient();
ns = client.GetStream();
}
ns.Write(byteTime, 0, byteTime.Length);
UpdateListBoxText(System.Text.Encoding.ASCII.GetString(byteTime));
ns.Read(buff, 0, buff.Length);

UpdateListBoxText(System.Text.Encoding.ASCII.GetString(buff));

}
catch (Exception e)
{
Console.WriteLine(e.ToString());
} }
client.Close();
listener.Stop();
}


//可能有错误,我是按照2楼的textbox进行的修改
//跨线程操作ListBox控件委托
delegate void SetListBoxCallback(string byteTime);
private void UpdateListBoxText(string byteTime)
{
if (this.ReceiveLB.InvokeRequired)
{
SetListBoxCallback m_SetListBoxCallBack = new SetListBoxCallback(UpdateListBoxText);
this.BeginInvoke(m_SetListBoxCallBack, new object[] { byteTime });

}
else
{
this.ReceiveLB.Items.Add(byteTime);
}
}

KING_314 2010-08-06
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qxw88 的回复:]
引用 1 楼 wxm3630478 的回复:
TcpListener listener = new TcpListener(portNum);

listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();

用一个方法封装......然后……
[/Quote]

谢谢这位朋友这么热心 根据2楼指点已经可以看到接收的数据包;
chazikai24 2010-08-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 foryouwife 的回复:]
用线程做。就不会卡死。你这样肯定会卡死的。
[/Quote]
UP
尤其是做循环的时候。数据量大的时候,一直会卡死,其实还是在运行的。
ViewStates 2010-08-06
  • 打赏
  • 举报
回复

//1st
ManualResetEvent mre=new ManualResetEvent(false);
int portNum = 8000;
bool done = false;

TcpListener listener = new TcpListener(portNum);

listener.Start();
//TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
while (!done)
{
//2nd
mre.Reset();
Console.Write("Waiting for connection...");
ReceiveLB.Items.Add("Waiting for connection...");
//3rd
TcpClient client = listener.AcceptTcpClient();
mre.WaitOne();
Console.WriteLine("Connection accepted.");
ReceiveLB.Items.Add("Connection accepted.");

byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());

byte[] buff=new byte[1000];
try
{
if (client==null)
{
//???
client = listener.AcceptTcpClient();
ns = client.GetStream();
//4th
mre.Set();
}
//写数据
ns.Write(byteTime, 0, byteTime.Length);
//ReceiveLB为listbox,采用线程的话会报线程中无法调用
ReceiveLB.Items.Add("send:"+System.Text.Encoding.ASCII.GetString(byteTime));
MessageBox.Show(System.Text.Encoding.ASCII.GetString(byteTime));
//读数据
ns.Read(buff, 0, buff.Length);
ReceiveLB.Items.Add("receive:" + System.Text.Encoding.ASCII.GetString(buff));
MessageBox.Show(System.Text.Encoding.ASCII.GetString(buff));
//ns.Close();
//client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

}

client.Close();
listener.Stop();

KING_314 2010-08-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wxm3630478 的回复:]
TcpListener listener = new TcpListener(portNum);

listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();

用一个方法封装......然后用线程启动 (Thread类)

……
[/Quote]
额 用线程的话 我绑定到listBox 现在没有出现假死的情况 谢谢
  • 打赏
  • 举报
回复
建议重新开个线程,阻塞的内容放在新开的线程里。
ggw128 2010-08-06
  • 打赏
  • 举报
回复
支持用线程做,以前做到基于UDP协议的文件通讯。
hupengcscs 2010-08-06
  • 打赏
  • 举报
回复
上面的说的很清楚了。
KING_314 2010-08-06
  • 打赏
  • 举报
回复
谢谢各位指点 我尝试下

111,094

社区成员

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

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

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