Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何使用Delphi从线程更新GUI_Multithreading_Delphi - Fatal编程技术网

Multithreading 如何使用Delphi从线程更新GUI

Multithreading 如何使用Delphi从线程更新GUI,multithreading,delphi,Multithreading,Delphi,我使用Delphi匿名线程来执行代码。 在线程的中间,有两个GUI更新必须发生,一对标签改变等。 如果从线程内部执行此操作,则会发生更改,但只要线程停止。它们消失,然后应用程序给我旧的窗口处理程序错误…(这是意料之中的) 系统错误。代码:1400。无效的窗口句柄 我尝试使用Syncronize(updateui)方法来执行更改(将它们移动到一个单独的函数),但我在syncronizeE2066缺少运算符或分号时出错,这对我来说毫无意义 我已经搜索了一页又一页,他们似乎都这么说,但当我这样做的时候

我使用Delphi匿名线程来执行代码。 在线程的中间,有两个GUI更新必须发生,一对标签改变等。 如果从线程内部执行此操作,则会发生更改,但只要线程停止。它们消失,然后应用程序给我旧的窗口处理程序错误…(这是意料之中的)

系统错误。代码:1400。无效的窗口句柄

我尝试使用
Syncronize(updateui)方法来执行更改(将它们移动到一个单独的函数),但我在syncronize
E2066缺少运算符或分号时出错,这对我来说毫无意义

我已经搜索了一页又一页,他们似乎都这么说,但当我这样做的时候,我得到了上面的错误

我说错了吗

代码:

使用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;