gpt4 book ai didi

multithreading - BeginThread 结构 - Delphi

转载 作者:行者123 更新时间:2023-12-03 15:05:00 24 4
gpt4 key购买 nike

我现在已经有了一个即将完成的应用程序,我想要实现的下一个功能是线程。我选择使用 BeginThread(),尽管我知道 delphi 中的 TThread。我遇到的问题是 BeginThread() 调用的结构。通常,程序中调用我想要线程化的函数的行是

CompareFiles(form1.Edit3.Text,Form1.Edit4.Text,Form1.StringGrid2,op);

op 是一个整数。

我将其切换为从中创建线程的行是

BeginThread(nil,0,CompareFiles,Addr('form1.Edit3.Text,Form1.Edit4.Text,Form1.StringGrid2,op'),0,x);

从少量信息中,我可以找到有关如何实际使用 BeginThread() 的信息,这应该是一个很好的调用,但是在编译时,我得到的只是有关 BeginThread() 语句参数结构的编译器错误。

编辑信息。

当前调用CompareFiles的过程是

procedure TForm1.Panel29Click(Sender: TObject);
var
op,x : integer;

begin
if (Form1.Edit3.Text <> '') AND (Form1.Edit4.Text <> '') then
begin
op := 3;
if RadioButton7.Checked = True then op := 0;
if RadioButton3.Checked = True then op := 1;
if RadioButton4.Checked = True then op := 2;
if RadioButton5.Checked = True then op := 3;
if RadioButton6.Checked = True then op := 4;
CompareFiles(form1.Edit3.Text,Form1.Edit4.Text,Form1.StringGrid2,op);
end;
end;

如果我按照几个人的建议使用 TThread,并且如下面 Rob 所示,我很困惑 a) 如何将 op、Edit3/4.Text 和 StringGrid2 传递给 CompareFiles。从我见过的 TThread 示例猜测,我想我应该用 TCompareFilesThread.Execute 替换上面的代码,并将 Panel29Click 中的当前代码放入 TCompareFilesThread.Create 中,然后添加

FEdit3Text := Edit3Text;
FEdit4Text := Edit4Text;
FGrid := Grid;

到此

FEdit3Text := Form1.Edit3.Text;
FEdit4Text := Form1.Edit4.Text;
FGrid := Form1.StringGrid2;

但我有一种完全不合时宜的挥之不去的感觉。

最佳答案

这根本不是使用BeginThread的方式。该函数需要一个指向带有一个参数的函数的指针,但您尝试调用的函数需要四个参数。您为 BeginThread 提供的用于转发到线程过程的一个参数是一个字符串,但您显然希望某种魔法能够将该字符串转换为这些变量包含的值.

这不是 Delphi 的工作方式,即使对于那些可以做类似事情的语言,通常也不鼓励实际它。

要将多个参数传递给 BeginThread,请定义一个包含您需要的所有值的记录,并定义一个记录指针:

type
PCompareFilesParams = ^TCompareFilesParams;
TCompareFilesParams = record
Edit3Text,
Edit4Text: string;
Grid: TStringGrid;
Op: Integer;
end;

更改CompareFiles以接受指向该记录的指针:

function CompareFiles(Params: PCompareFilesParams): Integer;

要启动线程,您需要分配该记录的一个实例并填充其字段:

var
Params: PCompareFilesParams;
begin
New(Params);
Params.Edit3Text := Edit3.Text;
Params.Edit4Text := Edit4.Text;
Params.Grid := StringGrid2;
Params.Op := op;
BeginThread(nil, 0, @CompareFiles, Params, 0, x);

像这样实现CompareFiles,以便在线程终止之前释放记录:

function CompareFiles(Params: PCompareFilesParams): Integer;
begin
try
// <Normal implementation goes here.>
finally
Dispose(Params);
end;
end;

不过,如果您只使用 TThread,您可以使这一切变得更加容易。您可以让您的后代类在其构造函数中具有任意数量的参数,这样您就不必费力地动态分配和释放特殊记录。

type
TCompareFilesThread = class(TThread)
private
FEdit3Text,
FEdit4Text: string;
FGrid: TStringGrid;
FOp: Integer;
procedure Execute; override;
public
constructor Create(const Edit3Text, Edit4Text: string; Grid: TStringGrid; Op: Integer);
property ReturnValue;
end;

constructor TCompareFilesThread.Create;
begin
inherited Create(False);
FEdit3Text := Edit3Text;
FEdit4Text := Edit4Text;
FGrid := Grid;
FOp := Op;
end;

procedure TCompareFilesThread.Execute;
begin
ReturnValue := CompareFiles(FEdit3Text, FEdit4Text, FGrid, FOp);
end;

您只需实例化该类并让它运行,而不是调用 BeginThread:

var
ThreadRef: TThread;


ThreadRef := TCompareFilesThread.Create(Edit3.Text, Edit4.Text, StringGrid2, Op);

使用线程还有更多内容,例如知道线程何时完成运行,但我认为您已经足够开始了。不过,最后要注意的一件事是 TStringGrid 是一个 VCL 控件。您不能从您创建的这个新线程中对其执行任何操作(无论您最终如何创建它)。您对网格控件所做的一切都需要从主线程完成。使用 TThread.SynchronizeTThread.Queue 将任何 VCL 操作转移到主线程上。您的文件比较线程将等待同步操作完成,但它将继续运行,而不等待排队操作完成。

关于multithreading - BeginThread 结构 - Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4788993/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com