穿线问题 [英] Threading Problem
问题描述
大家好,
我对线程化TCP服务器有问题.我使用侦听线程来处理所有传入的TCP连接.但是,由于某种原因,我随机从Windows XP收到了此消息:
SCBC.exe遇到问题,需要关闭
如果我忽略此消息,则工作线程(处理tcp conn的线程)可以正常工作,但无法获得另一个传入的tcp连接.我认为问题在于侦听线程.似乎它在某个时候崩溃了.
我从此开始侦听线程:
Hi everyone,
I have a problem with a Threaded TCP Server. I use a listening Thread to handle all the incoming TCP connections. But, for some reason I ve got this messages from Windows XP at random times:
SCBC.exe has encountered a problem and needs to be shuted down
If I ignore this message the working threads (those which handle tcp conn) work fine, but I can''t get another incoming tcp connection. I think the problem is the listening thread. It seems it crashed down at some point.
I start the listening thread with this:
private Thread TCPServer;
public static List<Thread> processor;
TCPServer = new Thread(delegate()
{
new TCPServer();
});
TCPServer.Start();
这是TCP Server Obj的构造函数:
This is the constructor for the TCP Server Obj:
//Some code which handles a database
.
.
.
StartListening();
这是我的StartListening函数代码:
This is my code for the StartListening Function:
public TcpListener listener;
public static List<TcpClient> lstClientsTCP = new List<TcpClient>();
private void StartListening()
{
int foo = 0;
int bar = 0;
try
{
DB.ConnectDataBase();
lstClientsTCP = new List<TcpClient>();
byte[] bytes = new Byte[1024];
string Host = Dns.GetHostName();
IPHostEntry IPs = Dns.GetHostByName(Host);
IPAddress[] Direcciones = IPs.AddressList;
IPAddress ipAddress = IPAddress.Parse(Direcciones[0].ToString());
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, listenport);
while (true)
{
listener = new TcpListener(localEndPoint);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
client.ReceiveTimeout = 30000;
listener.Stop();
Thread tmpThread = null;
bar = foo;
tmpThread = new Thread(delegate() { ServiceClient(client, bar); });
FrmMain.processor.Add(tmpThread);
FrmMain.processor[foo].Start();
foo++;
if (foo == 999)
foo = 0;
}
}
catch (Exception ex)
{
Console.WriteLine("STARTLISTENING: " + ex.Message + "->" + ex.StackTrace);
}
}
DB对象是MySql数据库处理程序对象.
难道我做错了什么?我一直建议使用线程池(使用更少的内存),但是我不认为这是问题所在.如果您有任何想法,请告诉我,请原谅我的英语.
谢谢
Ivan
DB object is an MySql Database handler object.
Am I doing something wrong? I ve been suggeste to use Thread Pools (use less memory), but I dont think thats the problem. If you have any ideas please let me know and excuse my english.
Thanks
Ivan
推荐答案
一些东西看起来很粗略:
*使用while (true)
循环,线程如何终止?请不要通过Thread.Abort()
保存.
*无需为循环的每次迭代创建新的TcpListener
.只需在循环之前调用Start
创建一个实例,并且在循环之后仅调用一次Stop
.
*用foo
的整个位,将线程添加到列表中,并在foo
的999完全不可用时将其回滚到0.如果foo
滚动过来,那是一个直接的错误.对Add
的调用将在索引998处插入新线程,将调用processor[998].Start
,然后foo
翻转.下次通过循环时,线程将在索引999处添加,但由于再次调用了在processor[0].Start
上滚动的foo
.失败.所有这些还假设没有人从列表中删除线程,一旦线程完成运行以确保您最终不会耗尽资源,就应该在列表中删除线程.另外,其他线程是否访问processor
?如果是这样,则需要使用lock
语句对其进行保护.
如果所有其他方法均失败,则应该可以使用未处理的ExceptionHandler [
a few things look sketchy:
* with awhile (true)
loop how does the thread ever terminate? Please don''t save that viaThread.Abort()
.
* there''s no need to create a newTcpListener
for every iteration of the loop. There only needs to be one instance created withStart
called before the loop, andStop
needs to be called only once after the loop.
* that whole bit withfoo
, adding the thread to a list and rollingfoo
back over to 0 when it''s 999 is entirely shady. Iffoo
rolls over then that''s an immediate bug right there. The call toAdd
will insert the new thread at index 998,processor[998].Start
will be called, thenfoo
rolls over. The next time through the loop the thread is added at index 999 but sincefoo
rolled overprocessor[0].Start
is being called again. Fail. All of this also assumes that no one is ever removing threads from the list, which should be happening somewhere once the threads have finished running to ensure that you don''t run out of resources eventually. Also, do other threads accessprocessor
? If so then it needs to be protected with alock
statement.
If all else fails you should be able to use the Unhandled ExceptionHandler[^] to help find out the root cause of the problem.
首先要尝试使用的是 SafeThread-防止辅助线程中出现未处理的异常 [ ^ ],以确保未处理的异常不是罪魁祸首.
the first thing to try is using SafeThread - Prevent Unhandled Exceptions in Secondary Threads[^] to make sure unhandled exceptions aren''t the culprit.
这篇关于穿线问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!