Hier mal ein paar Teile Code. Der besagte Thread:
Delphi-Quellcode:
procedure TdxIDTPSendThread.Execute;
var
I, X, Y: Integer;
List: TList;
Transfer: TdxIDTPTransfer;
begin
while (not Terminated) do
begin
List := FWriter.TransferList.LockList;
try
X := 0;
Y := 0;
for I := 0 to List.Count - 1 do
begin
//
// !! Code gekürzt: An dieser Stelle wird das OnProgress Event aufgerufen !!
//
if (not Transfer.Priority) then
begin
Inc(X);
end;
Inc(Y);
end;
// Beendete Transfers entfernen
for I := List.Count - 1 downto 0 do
begin
Transfer := TdxIDTPTransfer(List[I]);
if (Transfer.TransferState = tsFinished) then
begin
List.Delete(I);
Transfer.Free;
end;
end;
finally
FWriter.TransferList.UnlockList;
end;
Sleep(10);
// Thread suspendieren
if (Y = 0) then
begin
{$WARNINGS OFF}
Suspend;
{$WARNINGS ON}
end;
end;
end;
Die Funktion, die von der
GUI aus aufgerufen werden kann:
Delphi-Quellcode:
function TdxIDTPWriter.SendFile(Filename: String; Offset: Int64;
TransferCode: Word; Encrypt: Boolean; const Compress, Priority: Boolean;
const CreateSuspended: Boolean;
const PacketSize: TdxPacketSize): TdxIDTPTransfer;
var
List: TList;
begin
Result := TdxIDTPFileTransfer.Create(FSendThread, Filename, Offset,
GenerateTransferID, TransferCode, Priority, Encrypt, Compress, PacketSize);
List := FTransferList.LockList;
try
//
// !! Hier kommt es zum Deadlock !!
//
List.Add(Pointer(Result));
finally
FTransferList.UnlockList;
end;
if (CreateSuspended) then
begin
Result.Suspend;
end else if (FSendThread.Suspended) then
begin
{$WARNINGS OFF}
FSendThread.Resume;
{$WARNINGS ON}
end;
end;
Mein Code im Event:
Delphi-Quellcode:
var
Item: TListItem;
begin
AsyncCalls.EnterMainThread;
try
Item := TListItem(Transfer.Data);
Item.SubItems[1] := IntToStr(Progress);
finally
AsyncCalls.LeaveMainThread;
end;
Lasse ich den Code im Event beispielsweise ganz weg oder verzichte Testweise auf die Synchronisierung kommt es beim Aufruf von SendFile nicht zum Deadlock. Mit der Synchronisation allerdings schon.