穿线问题 [英] Threading Problem

查看:61
本文介绍了穿线问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我对线程化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 a while (true) loop how does the thread ever terminate? Please don''t save that via Thread.Abort().
* there''s no need to create a new TcpListener for every iteration of the loop. There only needs to be one instance created with Start called before the loop, and Stop needs to be called only once after the loop.
* that whole bit with foo, adding the thread to a list and rolling foo back over to 0 when it''s 999 is entirely shady. If foo rolls over then that''s an immediate bug right there. The call to Add will insert the new thread at index 998, processor[998].Start will be called, then foo rolls over. The next time through the loop the thread is added at index 999 but since foo rolled over processor[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 access processor? If so then it needs to be protected with a lock 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆