这个简单,如果IdTCPServer组件不为OnExecute指定处理过程,就会得到EIdNoExecuteSpecified
异常,你可以查看以下两个代码片段:
function TIdTCPServer.DoExecute(AThread: TIdPeerThread): boolean;
var
i: integer;
LLine: string;
begin
if CommandHandlersEnabled and (CommandHandlers.Count > 0) then begin
Result := True;
if AThread.Connection.Connected then begin //APR: was While, but user can disable handlers
LLine := AThread.Connection.ReadLn;
// OLX sends blank lines during reset groups and expects no response. Not sure
// what the RFCs say about blank lines.
// I telnetted to some newsservers, and they dont respond to blank lines.
// This unit is core and not NNTP, but we should be consistent.
if Length(LLine) > 0 then begin
DoBeforeCommandHandler(AThread, LLine); try
for i := 0 to CommandHandlers.Count - 1 do begin
with CommandHandlers.Items[i] do begin
if Enabled then begin
if Check(LLine, AThread) then begin
Break;
end;
end;
end;
if i = CommandHandlers.Count - 1 then begin
DoOnNoCommandHandler(LLine, AThread);
end;
end;//for
finally DoAfterCommandHandler(AThread); end;
end;//if >''
end;
end else begin
Result := Assigned(OnExecute);//注意这里,当你没有为OnExecute指定处理是该函数就会返回False;
if Result then begin
OnExecute(AThread);
end;
end;
end;
procedure TIdPeerThread.Run;
begin
try
try
if not Connection.Server.DoExecute(Self) then begin//如果DoExecute返回False抛出异常
raise EIdNoExecuteSpecified.Create(RSNoExecuteSpecified);
end;
。。。。。。。
end;
procedure TIdThread.Execute;
begin
try
try
BeforeExecute;
while not Terminated do begin
if Stopped then begin
DoStopped;
// It is possible that either in the DoStopped or from another thread,
// the thread is restarted, in which case we dont want to restop it.
if Stopped then begin // DONE: if terminated?
if Terminated then begin
Break;
end;
Suspended := True; // Thread manager will revive us
if Terminated then begin
Break;
end;
end;
end;
try
BeforeRun;
try
////////////////////////注意这里////////////////////
//一有连接线程创建时执行的事件
while not Stopped do begin
Run;
end;
finally
AfterRun;
end;//tryf
finally
Cleanup;
end;
end;//while NOT Terminated
finally
AfterExecute;
end;
except
on E: Exception do begin
FTerminatingExceptionClass := E.ClassType;
FTerminatingException := E.Message;
DoException(E);
Terminate;
end;
end;//trye
end;
//这是被调用的方法
procedure TIdPeerThread.Run;
begin
try
try
//如果没有写DoExecute事件,则异常
if not Connection.Server.DoExecute(Self) then begin
raise EIdNoExecuteSpecified.Create(RSNoExecuteSpecified);
end;
except
// We handle these seperate as after these we expect .Connected to be false
// and caught below. Other exceptions are caught by the outer except.
on E: EIdSocketError do begin
Connection.Server.DoException(Self, E);
case E.LastError of
Id_WSAECONNABORTED // WSAECONNABORTED - Other side disconnected
, Id_WSAECONNRESET:
Connection.Disconnect;
end;
end;
on E: EIdClosedSocket do begin
// No need to disconnect - this error means we are already disconnected or never connected
Connection.Server.DoException(Self, E);
end;
on E: EIdConnClosedGracefully do begin
// No need to Disconnect, .Connected will detect a graceful close
Connection.Server.DoException(Self, E);
end;
end;
// If connection lost, stop thread
//如果没有断开连接,则一直执行...........所以占用资源100%
if not Connection.Connected then begin
Stop;
end;
// Master catch. Catch errors not known about above, or errors in Stop, etc.
// Must be a master catch to prevent thread from doing nothing.
except
on E: Exception do begin
Connection.Server.DoException(Self, E);
raise;
end;
end;
end;