See what in a service takes CPU Edit: (Many Threads...)

I have a C# Service, that is quite big, it works as a server application having communication with a few (about 5) clients at the same time. Each client is a Thread that mostly puts data in and takes data out of a Access database. The service works well when its started, but after a few days the CPU just goes wild (up on 99%) and the service starts to slow down alot. I dont know what is causing this... Is there anyway to see WHAT in a service that takes the CPU, what function och thread? Dont know how to describe it better, but just ask questions if you need more info to help! :)

/Nick

EDIT: Added code on how I create threads and what they do.... (After i used Process Expolorer i noticed I hade alot running)

private void ListenForClients()
{
            this.tcpListener.Start();

            while (true)
            {
                TcpClient client = this.tcpListener.AcceptTcpClient();

                Connection c = new Connection(this.parent);
                Thread clientThread = new Thread(new ParameterizedThreadStart(c.HandleClientComm));

                threadCollection.Add(clientThread);
                clientThread.Start(client);
            }
}

public void HandleClientComm(object client)
    {
        try
        {

            TcpClient server = (TcpClient)client;

            NetworkStream ns = server.GetStream();
            byte[] data = new byte[1024];
            string input, stringData;

            while (true)
            {
                try
                {
                    data = new byte[1024];
                    if (ns.DataAvailable && ns.CanRead)
                    {
                        int recv = ns.Read(data, 0, data.Length);
                        if (recv > 0)
                        {
                            if ((byte)data[recv - 1] == (byte)255)
                            {
                                int cnt = -1;
                                for (int i = 0; i < recv; i++)
                                {
                                    if (data[i] == (byte)254)
                                        cnt = i;
                                }

                                int nr = recv - cnt - 2;
                                byte[] tmp = new byte[nr];

                                for (int i = 0; i < nr; i++)
                                {
                                    tmp[i] = data[cnt + i + 1];
                                }
                                string crc = Encoding.UTF8.GetString(tmp);
                                stringData = Encoding.UTF8.GetString(data, 0, cnt);

                                MsgStruct msgs = new MsgStruct(stringData);
                                msgs.setCrc(crc);
                                Thread.Sleep(200);

                                addTodo(msgs);
                            }
                        }


                    }
                    if (parent.cStructHandler.gotMsg(this.ID))
                    {
                        MsgStruct tmpCs = parent.cStructHandler.getNextMsg(this.ID);

                        if (tmpCs.getMsg().Length != 0 && ns.CanWrite)
                        {
                            byte[] ba = Encoding.UTF8.GetBytes(tmpCs.getMsg());

                            if (tmpCs.getCrc() == "")
                            {
                                ulong tmp = CRC.calc_crc(ba, ba.Length);
                                tmpCs.setCrc(tmp.ToString("X"));
                            }

                            if (tmpCs.canSendByTimeout())
                            {
                                string crcStr = "?" + tmpCs.getCrc() + "?";
                                byte[] bb = Encoding.UTF8.GetBytes(crcStr);
                                crcStr = Encoding.UTF8.GetString(bb);
                                byte[] fullMsg = new byte[ba.Length + bb.Length];
                                bb[0] = 254;
                                bb[bb.Length - 1] = 255;

                                ba.CopyTo(fullMsg, 0);
                                bb.CopyTo(fullMsg, ba.Length);
                                string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg);

                                ns.Write(fullMsg, 0, fullMsg.Length);
                                Thread.Sleep(200);
                                if (!tmpCs.isAckNeeded())
                                    parent.cStructHandler.removeNextMsg(this.ID);
                            }
                        }
                    }

                    Thread.Sleep(100);
                }
                catch (Exception e)
                {
                    break;
                }

            }
            ns.Close();
            server.Close();

        }
        catch (Exception e)
        {
        }
    }

Answers


I suggest you use some kind of tracing, just to see what your appication is doing:

Here is a simple logging framework for dot net log 4 net Tutorial

And: As you stated it is a long running server process, I recommend using rolling logs (i.e. if a logfile has a certain amount of lines, a new file is used). The log4net RollingFileAppender comes in handy.

You should use a high level of tracing for the standard case (i.e. while everything is working just fine) and be able to switch to lower levels with more output when in need (i.e. when your serverprocess goes amok).

And, of course, you could have a look via the jetbrains tool

Also highly recommend are those RedGate Tools: ANTS performance profiler and the Dot Net Reflector

EDIT

Almost forgot to mention: One of my favorite tools of all times: Process Explorer

EDIT2

In case of work done, you will need a break to leave the while true, i think


Try to check opened handles (files). I bet you forgot to free native resources (forgot about using construction)


Main issue in your code is that you are generating threads indefinitely and probably not freeing them at all in threadCollection.

Maybe ThreadPool.QueueUserWorkItem "fire & forget" is better in your case?


Need Your Help

cipher class and mcrypt_create_iv is slow at times

php mcrypt encryption

I am having an issue with my cipher class. At times it is very fast. Sometimes however it is slow. the code Im using is as follows

Delphi C++Builder to VisualStudio

visual-studio-2005 c++builder

Can we 'easily' (in some way) compile C++Builder project into VisualStudio 2005 C++. New in C++ i'm looking for references in that matter (CBuilder vs VS). Thanks.