我遇到了一些代码问题,这些代码是由现在离开我们公司的开发人员编写的,代码实现了一个响应基于XML协议的tcpserver。这似乎在我们的测试环境中工作得非常好,但是有一两个客户在应用程序关闭时遇到问题。
我已经将此跟踪到了调用tidtcpserver.active = false时看似死锁的内容。我已经知道,其中一个连接步骤可以对主线程进行同步调用,而主线程正在等待连接线程终止,从而导致死锁。
我已经在使用tidthreadsafestringlist将数据传递给主线程进行处理,而我需要从主线程中调用一个过程,我创建了一个tidnotify后代来执行此操作。任何人都可以想到要寻找的其他东西。
我一直在检查异常处理,
这就是我在onexecute事件中所拥有的
try
// code to handle connection including tidnotify etc....
except
on E:Exception do
begin
if (e.InheritsFrom(EIdSilentException) = False) then
TXMLTraceNotify.XMLTrace('TCPServerExecute: ' + E.Message,ttProblem, FTraceProc);
raise; //we must raise all exceptions for indy to handle them.
end;
端;
以下是我如何使用TS-stringlist
声明。
public
TransactionStrings: TIdThreadSafeStringList;
它在构造函数中创建并在析构函数中销毁。
这就是我在tcpserver的上下文中添加它的方式。
TransactionStrings.Add(newTrans.AsString);
这就是我在主应用程序线程
的上下文中从中读取的内容slXMLTrans := TStringList.Create;
try
slTemp := FCustomXMLServer.TransactionStrings.Lock;
try
slXMLTrans.Assign(slTemp);
slTemp.Clear;
finally
FCustomXMLServer.TransactionStrings.Unlock;
end;
if slXMLTrans.Count > 0 then
begin
for i := 0 to Pred(slXMLTrans.Count) do
TAbstractTerminal.ProcessXMLTrans(slXMLTrans[i]);
slXMLTrans.Clear;
end;
finally
slXMLTrans.Free;
end;
我认为这是使用它的正确方法,但我等待你的评论。
答案 0 :(得分:0)
将Active属性设置为False时的死锁是一个经典的,经常讨论的问题,当错误地使用TIdTCPServer时。服务器死锁的唯一方法是连接线程未正确终止。这可能是由于主线程忙于停用服务器时将operaton与主线程同步引起的,在这种情况下,使用TIdNotify可以消除任何此类死锁条件。
但是,这不是阻止连接线程终止的唯一方法。另一种可能性是,如果您的服务器事件处理程序中有异常处理,则会阻止Indy的内部通知被处理。这可能会导致失控的线程继续运行,但永远不会知道它们需要停止。如果要捕获代码中的异常,请确保重新抛出任何EIdException派生的异常,并让服务器在内部处理它们。