解决方案 »
- C# 连接权限错误
- SQLDMO备份SQLServwr2005数据库不显示进度条?
- 简单C#多线程问题,有问题请教高手
- 请大家帮我看下这个TreeView遍历算法有何隐患?
- 如何利用vs2005 Team版进行团队开发?
- 运行时的错误信息不能在客户端显示详细错误?都是/服务器应用程序错误,要你设置customErrors 的mode。如果要在客户端出现详细的错误信息
- C#从哪个版本开始,会自动给没有赋初始值的类成员一个默认值?
- 在DATAGRID中的模板列中添加了一个CHECKBOX却不知道怎样引发它的CHECKED事件?
- calendar中的属性SelectedDate要设为当前时间为什么不对?
- wrox的《C#高级编程》对初学者适合吗?读者有C++经验。
- c#的窗口如何捕获windows+D的事件呢
- 界面的滚动。
{
try
{
MessageBox.Show("监听开始!");
client = listener.AcceptSocket();
}
---------------------------------
我的做法是:
1.为这个类增加一个bool成员,Listening。
2.上面的while循环改成:while(Listening)
3.循环内部:
if(listener.Pending)
//Accept
else
Thread.Sleep(300);
4.要终止的话,Listening=false;当然,这样做的缺点就是CPU消耗时间会有一定的增加。
谢谢你的帮助,问题解决了。
我看了一下Abort() 的介绍,貌似用这个方法就一定会产生异常信息的,但是这个方法既然存在就一定有它的道理,请问这个方法该在什么时候用呢?使用的时候该做什么处理?该注意些什么?
就用ThreadPool吧.比Thread方便10000倍!
ThreadPool.QueueWorkItem(YourMethod);
我已经这样做了,这是新的代码: public partial class Form1 : Form
{
Thread createServer = null;
ServerThread listener = null; public Form1()
{
InitializeComponent();
} //启动服务端监听线程
private void button1_Click(object sender, EventArgs e)
{
createServer = new Thread(new ThreadStart(WaitForConnect));
createServer.Start();
} private void WaitForConnect()
{
listener = new ServerThread();
listener.StartListening();
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (listener != null)
listener.Dispose();
if (createServer != null)
createServer.Abort(); MessageBox.Show("清理完毕1");
}
catch
{}
}
}
class ServerThread
{
int port = 9000; //监听端口号
IPAddress localAddr = IPAddress.Parse("127.0.0.1"); TcpListener listener = null;
Socket client = null; bool listening = true; public void StartListening()
{
listener = new TcpListener(localAddr,port);
listener.Start(); while (listening)
{
try
{ MessageBox.Show("监听开始!");
client = listener.AcceptSocket(); }
catch (Exception e)
{
MessageBox.Show(e.ToString());
} }
try
{
if (client != null)
{
client.Close();
client = null;
}
listener.Stop();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
} public void Dispose()
{
listening = false;
}
}
结果还是不行。当我强制关闭窗口的时候,调试信息为:
线程 0xc70 已退出,返回值为 0 (0x0)。
线程 '<无名称>' (0x1748) 已退出,返回值为 0 (0x0)。
“Server.vshost.exe”(托管): 已加载“D:\编程工具\C#程序\网格\NetGrid\Server\bin\Debug\Server.exe”,符号已加载。
“Server.vshost.exe”(托管): 已加载“C:\WINDOWS\assembly\GAC_MSIL\System.Configuration\2.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll”,未加载符号。
“Server.vshost.exe”(托管): 已加载“C:\WINDOWS\assembly\GAC_MSIL\mscorlib.resources\2.0.0.0_zh-CHS_b77a5c561934e089\mscorlib.resources.dll”,未加载符号。
线程 '<无名称>' (0xffc) 已退出,返回值为 0 (0x0)。
线程 0x12b4 已退出,返回值为 0 (0x0)。当我关闭调试后,就多了句:程序“[3516] Server.vshost.exe: 托管”已退出,返回值为 0 (0x0)。这时程序才真正退出,程序进程才在进程管理器里消失。问题一个个来,郁闷死……
Java中有守护线程,C#中有线程池.
他们都会在程序主线程main结束时自动退出.
这才是正到
请问
if(listener.Pending())
//Accept
else
Thread.Sleep(300);
这段貌似有点错误吧,我认为应该是这样:
if(!listener.Pending())
//Accept
else
Thread.Sleep(300);
当没有监听挂起的时候才去监听
学习ing
我改了一下我的代码: if (listener.Pending())
{
MessageBox.Show("监听开始!");
client = listener.AcceptSocket();
}
else
{
MessageBox.Show("没有挂起!");
listening = false;
}
我试了一下,当我改成您这样的写法的时候,点击监听摁钮时,发现执行的是MessageBox.Show("没有挂起!")这一段。因为我没有写客户端来测试,所以我现在这样猜想:当执行了listener.Start()后,因为没有客户端连接近来,所以listener.Pending()为false;当有客户端连接进来的时候,listener.Pending()就为true,这时就执行client = listener.AcceptSocket()来接受客户端的连接请求。不知道我理解对了吗?
所以我那个在Pending为false的时候一直执行Thread.Sleep,让出CPU时间。
当然,执行方法本身要浪费点时间。
public void StartListening()
{
listener = new TcpListener(localAddr, port);
listener.Start();
listening = true; while (listening)
{
try
{
if (listener.Pending())
{
MessageBox.Show("监听开始!");
client = listener.AcceptSocket();
}
else
Thread.Sleep(300);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
} } try
{
if (client != null)
{
client.Close();
client = null;
}
listener.Stop();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
} public void Dispose() //终止循坏监听
{
listening = false;
}//主窗口
//强制退出
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
if (listener != null)
listener.Dispose(); if (createServer != null)
{
createServer.Abort();
MessageBox.Show("终止了createServer");
}
MessageBox.Show("清理完毕1");
}
catch (ThreadAbortException ex)
{
MessageBox.Show(ex.ToString());
}
}这时有个新问题发生。当执行了监听的时候,因为没有客户连接进来,所以在服务端监听类里不断执行着Thread.Sleep(300),这时我强制退出,触发了服务端监听类里的Dispose()方法,使得循环退出。紧接着执行主窗口createServer.Abort()方法来终止线程。这时又弹出异常信息,显示要强制中断服务端监听类里的Thread.Sleep(300)线程。我不是已经退出循环了吗,干嘛Thread.Sleep(300)这个线程不一起终止呢?我取消createServer.Abort()这句后就能正常退出,因为前面我已经把服务端监听类开辟为一个后台线程了。但是现在取消createServer.Abort()这句虽然能退出程序,但是我担心会留下什么后遗症。这个有什么解决办法吗?
你可以在Dispose之后插入一个Thread.Sleep(300);这个时候,即使你不使用Abort,线程也会自然终止。
private static EventWaitHandle ewh_exception = new EventWaitHandle(false, EventResetMode.ManualReset); while (true)
{
try
{
if(ewh_exception.waitOne(0,false))
{
ewh_exception.reset();
break;
}
if (listener.Pending())
{
MessageBox.Show("监听开始!");
client = listener.AcceptSocket();
}
else
Thread.Sleep(300);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
} }
如果你想结束,先ewh_exception。set();跳出循环之后,你在把socket释放。