Multithreading 如何使用Delphi从线程更新GUI
我使用Delphi匿名线程来执行代码。 在线程的中间,有两个GUI更新必须发生,一对标签改变等。 如果从线程内部执行此操作,则会发生更改,但只要线程停止。它们消失,然后应用程序给我旧的窗口处理程序错误…(这是意料之中的)Multithreading 如何使用Delphi从线程更新GUI,multithreading,delphi,Multithreading,Delphi,我使用Delphi匿名线程来执行代码。 在线程的中间,有两个GUI更新必须发生,一对标签改变等。 如果从线程内部执行此操作,则会发生更改,但只要线程停止。它们消失,然后应用程序给我旧的窗口处理程序错误…(这是意料之中的) 系统错误。代码:1400。无效的窗口句柄 我尝试使用Syncronize(updateui)方法来执行更改(将它们移动到一个单独的函数),但我在syncronizeE2066缺少运算符或分号时出错,这对我来说毫无意义 我已经搜索了一页又一页,他们似乎都这么说,但当我这样做的时候
系统错误。代码:1400。无效的窗口句柄
我尝试使用Syncronize(updateui)代码>方法来执行更改(将它们移动到一个单独的函数),但我在syncronizeE2066缺少运算符或分号时出错,这对我来说毫无意义
我已经搜索了一页又一页,他们似乎都这么说,但当我这样做的时候,我得到了上面的错误
我说错了吗
代码:
使用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();
同步通常很昂贵(关于性能)。只有在真正必要的时候才做。如果扩展updateui方法以减少绘制操作,则可以提高性能
这可以通过以下方式呼叫:
在updateui()的顶部添加对StopDrawing()的调用,并在updateui()的末尾添加对ContinueDrawing()的调用。对ContinueDrawing()的调用应位于中。这将确保即使在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;
使用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();
同步通常很昂贵(关于性能)。只有在真正必要的时候才做。如果扩展updateui方法以减少绘制操作,则可以提高性能
这可以通过以下方式呼叫:
在updateui()的顶部添加对StopDrawing()的调用,并在updateui()的末尾添加对ContinueDrawing()的调用。对ContinueDrawing()的调用应位于中。这将确保即使在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;
太棒了,你是金星:),非常感谢你,它就像一个符咒。Marcel如果读了你之前问题的评论,这个答案正是我们告诉你的……我相信cnStartDrawing=0;应为cnStartDrawing=1;多少钱!?:)匿名线程非常昂贵,我知道在更新我的备忘录表单时,我会损失多少性能,比如匿名线程和同步!!太棒了,你是金星:),非常感谢你,它就像一个符咒。Marcel如果读了你之前问题的评论,这个答案正是我们告诉你的……我相信cnStartDrawing=0;应为cnStartDrawing=1;多少钱!?:)匿名线程非常昂贵,我知道在更新我的备忘录表单时,我会损失多少性能,比如匿名线程和同步!!绝对不能从其他线程访问控件。不写也不读@SirRufo我必须。。。数据库操作之间有很多变化。每个数据库操作都需要一些时间,如果不在线程中执行,主GUI看起来就像在运行一样。所以我必须把它全部穿上或者什么都不穿……我没有说“不要用线”。我只是说“不要从与主线程不同的任何线程访问(读/写)控件”,您根本不能从不同的线程访问控件。不写也不读@SirRufo我必须。。。数据库操作之间有很多变化。每个数据库操作都需要一些时间,如果不在线程中执行,主GUI看起来就像在运行一样。所以我必须把它全部穿上或者什么都不穿……我没有说“不要用线”。我只是说“不要从与主线程不同的任何线程访问(读/写)控件”
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;