我有一个C#服务,它非常大,它可以作为服务器应用程序同时与少数(约5个)客户端进行通信。每个客户端都是一个主要将数据放入并从Access数据库中取出数据的线程。该服务在启动时运行良好,但几天之后CPU就会疯狂(达到99%)并且服务开始减速很多。我不知道是什么导致了这个...无论如何在服务中看到什么需要CPU,什么功能och线程?不知道如何更好地描述它,但如果您需要更多信息来帮助,只需提出问题! :)
/尼克
编辑:添加了关于我如何创建线程以及他们做什么的代码....(在我使用Process Expolorer之后,我注意到我很喜欢运行)
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)
{
}
}
答案 0 :(得分:1)
我建议您使用某种跟踪,只是为了查看您的应用正在做什么:
这是dot net log 4 net Tutorial
的简单日志框架并且:正如您所说,这是一个长期运行的服务器进程,我建议使用 滚动日志(即,如果日志文件具有一定数量的行,则为新文件 用来)。 log4net RollingFileAppender派上用场。
您应该对标准情况使用高级别的跟踪(即 一切都工作正常),并能够切换到较低的水平 在需要时(即当你的服务器进程陷入困境时)输出更多。
当然,您可以通过jetbrains tool
查看强烈建议使用RedGate工具:ANTS performance profiler和Dot Net Reflector
修改强>
几乎忘了提及:我最喜欢的工具之一:Process Explorer
<强> EDIT2 强>
如果工作完成,你需要休息一下才能真实,我想
答案 1 :(得分:0)
尝试检查已打开的句柄(文件)。
我打赌你忘了释放原生资源(忘了using
建设)
答案 2 :(得分:0)
您的代码中的主要问题是您无限期地生成线程,并且可能根本不会在threadCollection中释放它们。
也许ThreadPool.QueueUserWorkItem“火与忘记”在你的情况下会更好吗?