Fla*_*lyn 5 delphi multithreading beginthread
我现在有一个几乎完成的应用程序,我想要实现的下一个功能是线程.我选择使用BeginThread(),虽然我知道delphi中的TThread.我遇到的问题是BeginThread()调用的结构.通常,程序中调用我想要线程化的函数的行是
CompareFiles(form1.Edit3.Text,Form1.Edit4.Text,Form1.StringGrid2,op);
Run Code Online (Sandbox Code Playgroud)
op是一个整数.
我已经将它切换出来以便从中创建一个线程
BeginThread(nil,0,CompareFiles,Addr('form1.Edit3.Text,Form1.Edit4.Text,Form1.StringGrid2,op'),0,x);
Run Code Online (Sandbox Code Playgroud)
从我可以找到的关于如何实际使用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;
Run Code Online (Sandbox Code Playgroud)
如果我按照几个人的建议使用TThread,并且如下面Rob所示,我很困惑a)我将如何将op,Edit3/4.Text和StringGrid2传递给CompareFiles.从TThread的例子猜测我已经看过我以为我会替换上面的代码TCompareFilesThread.Execute并将当前代码从Panel29Click放入TCompareFilesThread.Create然后添加
FEdit3Text := Edit3Text;
FEdit4Text := Edit4Text;
FGrid := Grid;
Run Code Online (Sandbox Code Playgroud)
对此
FEdit3Text := Form1.Edit3.Text;
FEdit4Text := Form1.Edit4.Text;
FGrid := Form1.StringGrid2;
Run Code Online (Sandbox Code Playgroud)
但我有这种唠叨的感觉完全不合适.
Rob*_*edy 14
这不是在所有使用方式BeginThread.该函数需要一个指向函数的指针,该函数接受一个参数,但您尝试调用的函数需要四个.你给的一个参数,BeginThread为它转发给线程过程是一个字符串,但你显然希望某种魔力会变成字符该字符串成这些变量包含值.
这不是Delphi的工作方式,即使对于可以做类似事情的语言,通常也不鼓励实际做到这一点.
要传递多个参数BeginThread,请定义包含您需要的所有值的记录,并定义记录指针:
type
PCompareFilesParams = ^TCompareFilesParams;
TCompareFilesParams = record
Edit3Text,
Edit4Text: string;
Grid: TStringGrid;
Op: Integer;
end;
Run Code Online (Sandbox Code Playgroud)
更改CompareFiles为接受指向该记录的指针:
function CompareFiles(Params: PCompareFilesParams): Integer;
Run Code Online (Sandbox Code Playgroud)
要启动该线程,您需要分配该记录的实例并填充其字段:
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);
Run Code Online (Sandbox Code Playgroud)
CompareFiles像这样实现,以便在线程终止之前释放记录:
function CompareFiles(Params: PCompareFilesParams): Integer;
begin
try
// <Normal implementation goes here.>
finally
Dispose(Params);
end;
end;
Run Code Online (Sandbox Code Playgroud)
但是,如果你只是使用它,你可以轻松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;
Run Code Online (Sandbox Code Playgroud)
BeginThread您只需实例化该类并让它运行,而不是调用:
var
ThreadRef: TThread;
ThreadRef := TCompareFilesThread.Create(Edit3.Text, Edit4.Text, StringGrid2, Op);
Run Code Online (Sandbox Code Playgroud)
还有更多使用线程,比如知道线程何时完成运行,但我认为你已经足够开始了.但要注意的最后一点TStringGrid是VCL控件.你不能从你创建的这个新线程中做任何事情(无论你最终如何创建它).您使用网格控件执行的操作需要从主线程完成.使用TThread.Synchronize和TThread.Queue将任何VCL操作转移到主线程上.您的文件比较线程将等待同步操作完成,但它将继续运行而不等待排队操作完成.
| 归档时间: |
|
| 查看次数: |
4843 次 |
| 最近记录: |