是否有可能從線程調用CopyFileEx和CopyCallback/ProgressRoutine函數(ProgressBar.Position將被同步)?CopyFileEx可以從輔助線程調用嗎?
我可以在線程中聲明CopyCallback/ProgressRoutine函數嗎?我在@ProgressRoutine的CopyFileEx中得到錯誤:「需要變量」。
是否有可能從線程調用CopyFileEx和CopyCallback/ProgressRoutine函數(ProgressBar.Position將被同步)?CopyFileEx可以從輔助線程調用嗎?
我可以在線程中聲明CopyCallback/ProgressRoutine函數嗎?我在@ProgressRoutine的CopyFileEx中得到錯誤:「需要變量」。
當然這是可能的。回調函數將在調用CopyFileEx
的線程的上下文中調用。如果您需要同步某些UI命令,請使用Delphi通常的TThread.Synchronize
或其他任何您想要的線程間同步技術。
回調函數不能是線程類的方法。它需要匹配由API規定的簽名,因此它需要是獨立的功能。當你聲明它正確時,當你將它傳遞給CopyFileEx
時,你不需要使用@
運算符。
function CopyProgressRoutine(TotalFileSize, TotalBytesTransferred: Int64;
StreamSize, StreamBytesTransferred: Int64;
dwStreamNumber, dwCallbackReason: DWord;
hSourceFile, hDestinationFile: THandle;
lpData: Pointer): DWord; stdcall;
,您可以給回調函數訪問相關的線程對象與lpData
參數。傳遞給線程對象的引用爲參數,當你調用CopyFileEx
:
procedure TCopyThread.Execute;
begin
...
CopyResult := CopyFileEx(CurrentName, NewName, CopyProgressRoutine, Self,
@Cancel, CopyFlags);
...
end;
通過訪問線程對象,你可以調用對象的方法,包括其自身的進步套路,所以下面可能構成的整體的獨立功能。它可以將其他所有內容委託給對象的方法。在這裏,我假定該方法具有與獨立函數相同的參數,但省略了lpData
參數,因爲該參數將作爲Self
參數隱式傳遞。
function CopyProgressRoutine;
var
CopyThread: TCopyThread;
begin
CopyThread := lpData;
Result := CopyThread.ProgressRoutine(TotalSize, TotalBytesTransferred,
StreamSize, StreamBytesTransferred, dwStreamNumber,
dwCallbackReason, hSourceFile, hDestinationFile);
end;
設置'TProgressBar.Position'不需要'TThread.Synchronize' IMO。 'TProgressBar.SetPosition'方法從不分配控件的句柄,並通過自己切換線程上下文的'SendMessage'調用工作。 – kludg 2011-06-16 05:14:58
從技術上講,@Serg,有一個競賽條件。 'TProgressBar'在讀取'Handle'屬性之前檢查'HandleAllocated'。如果句柄已被分配,但在讀取'Handle'之前被破壞,則句柄將被重新分配到錯誤的線程中。這不太可能發生,所以'TProgressBar'可能是安全的。但是,一般來說,UI更新應該與UI線程同步。 – 2011-06-16 05:51:14
我可以在線程中聲明CopyCallback/ProgressRoutine函數嗎?我在@ProgressRoutine的CopyFileEx中得到錯誤:「需要變量」。 – maxfax 2011-06-16 11:22:04