Mar*_*cel 7 delphi multithreading
我正在使用Delphi匿名线程来执行代码.在线程的中间,必须进行一些GUI更新,一些标签更改等.
如果我从线程内部执行此操作,则会发生更改,但一旦线程停止.他们消失了,然后应用程序给我旧的窗口处理程序错误...(这是预期的)
System Error. Code:1400. Invalid window handle
我尝试使用该Syncronize(updateui);方法来执行更改(将它们移动到一个单独的函数),但是我在syncronize上得到一个错误,E2066 Missing operator or semicolon这对我来说根本没有意义......
我一页又一页地搜索过,他们似乎都这么称呼它,但是当我这样做时,我得到了上述错误......
我说错了吗?
码:
TThread.CreateAnonymousThread(
procedure
begin
main.Enabled:=false;
Loading.show;
label52.caption:=getfieldvalue(datalive.users,'users','credit_amount','user_id',user_id );
CoInitialize(nil);
if (length(maskedit1.Text)=maskedit1.MaxLength) and (pingip(serverip)=true) then
begin
if (strtofloat(label52.caption)>0) then
begin
....do some work....
Synchronize(updateui);
end
else Showmessage('Insufficient Funds. Please add funds to continue.');
end
else if (length(maskedit1.Text)<>maskedit1.MaxLength) then
begin
Showmessage('ID Number not long enough.');
end
else
begin
Showmessage('Could not connect to the server. Please check your internet connection and try again.');
end;
CoUnInitialize;
loading.close;
main.Enabled:=true;
end).start;
Run Code Online (Sandbox Code Playgroud)
UpdateUI:
procedure TMain.updateui;
var
birthdate,deathdate:TDate;
begin
Panel3.Show;
Label57.Caption := 'Change 1';
Label59.Caption := 'Change 2';
Label58.Caption := 'Change 3';
Label60.Caption := 'Change 4';
Label62.Caption := 'Change 5';
Label70.Caption := 'Change 6';
ScrollBox1.Color := clwhite;
end;
Run Code Online (Sandbox Code Playgroud)
Ste*_*zek 10
使用TThread.Synchronize并传递另一个匿名函数.然后你可以在匿名函数中调用updateui:
TThread.CreateAnonymousThread(
procedure
begin
// do whatever you want
TThread.Synchronize(nil,
procedure
begin
updateui();
end);
// do something more if you want
end
).Start();
Run Code Online (Sandbox Code Playgroud)
同步通常很昂贵(关于性能).只有在他们真正需要的时候才能做到.如果扩展updateui -method以减少绘制操作,则可以提高性能.
这可以通过WM_SETREDRAW调用SendMessage:
procedure StopDrawing(const Handle: HWND);
const
cnStopDrawing = 0;
begin
SendMessage(Handle, WM_SETREDRAW, cnStopDrawing, 0);
end;
procedure ContinueDrawing(const Handle: HWND);
const
cnStartDrawing = 1;
begin
SendMessage(Handle, WM_SETREDRAW, cnStartDrawing, 0);
// manually trigger the first draw of the window
RedrawWindow(Handle, nil, 0,
RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
Run Code Online (Sandbox Code Playgroud)
在updateui()的顶部添加对StopDrawing()的调用,并在updateui()的末尾调用ContinueDrawing ().对ContinueDrawing()的调用应该在finally块中.这将确保即使在执行updateui期间发生异常后也将绘制窗口.
例:
procedure TMain.updateui;
begin
try
StopDrawing(Handle);
Panel3.Show;
Label57.Caption := 'Change 1';
Label59.Caption := 'Change 2';
// ...
finally
// Code under finally gets executed even if there was an error
ContinueDrawing(Handle);
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5940 次 |
| 最近记录: |