Ich warte auf den Thread zu beenden, aber ohne Erfolg, es bleibt in der WaitFor() -Methode stecken; und kommt nicht zurück und steht dort auf unbestimmte Zeit.delphi thread waitfor unendlich (nie terminieren)
procedure TForm1.btnStopClick(Sender: TObject);
Kann mir jemand helfen?
Ich bin mit Delphi Berlin 10.1 Update 2 auf einem Windows 10-Version 64-Bit läuft 1709 16299,64
folgt dem Code:
unit untPrincipal;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
const
WM_TEST_SERVICE = WM_APP + 1;
type
TForm1 = class(TForm)
btnStart: TButton;
mmoOutput: TMemo;
btnStop: TButton;
procedure btnStartClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
private
{ Private declarations }
threadService: TThread;
procedure OnThreadTerminate(Sender: TObject);
procedure WMTestService(var msg: TMessage); message WM_TEST_SERVICE;
public
{ Public declarations }
end;
IThreadInfo = interface
['{B179712B-8B14-4D54-86DA-AB22227DBCAA}']
function IsRunning: Boolean;
end;
IService = interface
['{30934A11-1FB9-46CB-8403-F66317B50199}']
procedure ServiceCreate();
procedure ServiceStart(const info: IThreadInfo);
end;
TMyService = class(TInterfacedObject, IService)
private
handle: THandle;
public
constructor Create(const handle: THandle);
procedure ServiceCreate;
procedure ServiceStart(const info: IThreadInfo);
end;
TThreadService = class(TThread)
private
service: IService;
protected
procedure Execute; override;
public
constructor Create(const service: IService);
end;
TThreadInfo = class(TInterfacedObject, IThreadInfo)
private
thread: TThread;
public
constructor Create(const thread: TThread);
function IsRunning: Boolean;
end;
TThreadPost = class(TThread)
private
handle: THandle;
info: IThreadInfo;
protected
procedure Execute; override;
public
constructor Create(const handle: THandle; const info: IThreadInfo);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.btnStartClick(Sender: TObject);
var
service: IService;
begin
service := TMyService.Create(Self.handle);
threadService := TThreadService.Create(service);
threadService.OnTerminate := OnThreadTerminate;
threadService.Start;
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
if Assigned(threadService) then
begin
try
threadService.Terminate;
threadService.WaitFor;
finally
if Assigned(threadService) then
FreeAndNil(threadService);
end;
end;
end;
procedure TForm1.OnThreadTerminate(Sender: TObject);
begin
mmoOutput.Lines.Add(DateTimeToStr(Now()) + ' - procedure TForm1.OnThreadTerminate(Sender: TObject);');
end;
procedure TForm1.WMTestService(var msg: TMessage);
begin
mmoOutput.Lines.Add(DateTimeToStr(Now()) + ' - Service');
end;
{ TMyService }
constructor TMyService.Create(const handle: THandle);
begin
inherited Create();
Self.handle := handle;
end;
procedure TMyService.ServiceCreate;
begin
PostMessage(handle, WM_TEST_SERVICE, 0, 0);
end;
procedure TMyService.ServiceStart(const info: IThreadInfo);
var
thread: TThreadPost;
begin
while info.IsRunning do
begin
thread := TThreadPost.Create(handle, info);
try
thread.Start;
thread.WaitFor;
ShowMessage('Never Execute');
finally
thread.Free;
end;
end;
end;
{ TThreadService }
constructor TThreadService.Create(const service: IService);
begin
inherited Create(True);
Self.service := service;
end;
procedure TThreadService.Execute;
begin
service.ServiceCreate;
service.ServiceStart(TThreadInfo.Create(Self) as IThreadInfo);
end;
{ TThreadInfo }
constructor TThreadInfo.Create(const thread: TThread);
begin
inherited Create();
Self.thread := thread;
end;
function TThreadInfo.IsRunning: Boolean;
begin
Result := not thread.CheckTerminated;
end;
{ TThreadPost }
constructor TThreadPost.Create(const handle: THandle; const info: IThreadInfo);
begin
inherited Create(True);
Self.handle := handle;
Self.info := info;
end;
procedure TThreadPost.Execute;
begin
while info.IsRunning do
begin
PostMessage(handle, WM_TEST_SERVICE, 0, 0);
Sleep(1000);
end;
end;
end.
Warum würden Sie das kurz nach dem Start des Threads aufrufen? Warum haben Sie überhaupt einen Thread? Warum überprüft der Thread nie auf "Beendet"? –
Dieser Code soll nur ein Problem zeigen, das ich in einem größeren System habe, wo mehrere IService läuft und jeder seinen eigenen Thread hat, wenn ich das System finalisiere (Windows Service für den Fall) muss ich alle Threads beenden, Warten Sie, bis die gleichen fertig sind und andere Operationen ausgeführt werden. Das Problem ist, wenn ich fertig bin.jeder IService ist anders implementiert und in einigen Fällen laufen mehr Threads in ihnen, und dort habe ich das Problem gefunden – Passella
@ JerryDodge, Du hast gesagt, dass die WaitFor() Methode unnötig ist, aber wie warte ich auf das Ende von Thread dieser Punkt? danke – Passella