Delphi代码自动完成无法识别匿名方法

8
请创建一个新的FMX应用程序,添加一个按钮和一个备忘录以运行此示例。我有以下代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TTask.Run(procedure
            var
              client: TIdHTTP;
              result: string;
            begin
              client := TIdHTTP.Create(nil);
              try
                try
                  client.ReadTimeout := 4000;
                  client.ConnectTimeout := 4000;
                  result := client.Get('a valid url here just as test');
                  TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(result);
                                           end);
                except
                  on E: Exception do
                    begin
                      TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(E.Message);
                                           end);
                    end
                end;
              finally
                client.Free;
              end;
            end);
end;

我的代码按照预期工作,但问题出现在IDE中。如果我将光标放在匿名函数主体的某个位置,就会自动关闭finally语句。

我该如何解决这个问题?


首先,我在这里。

enter image description here

然后我按回车键,就会出现这个!

enter image description here

如果你把光标放在行的开头而不是结尾,你可以添加新的空格而不需要完成。如何解决这个问题?嗯,我已经发现这个问题是因为有这段代码:

TThread.Synchronize(nil, procedure
                         begin
                           Memo1.Lines.Add(result);
                         end);

如果您删除此代码,则问题不再发生。这是IDE中的一个错误吗?

3
我有一个 Delphi 单元,其中每个回车都会插入一个 end (所以,如果我按五次回车,就会得到五个 end)。这让我疯狂。我之前没见过这种行为在早期的 Delphi 版本中。 - Andreas Rejbrand
我也觉得这很奇怪,我看到Marco Cantu的《Object Pascal Handbook》建议使用这种模式(内部有except),我认为这很奇怪。 - Alberto Miola
已知问题:https://quality.embarcadero.com/browse/RSP-18079 - Dave Nottage
我发誓我记得大约一年前我问过一个类似但不完全相同的问题,但是找不到了。基本上,在相同的情况下,当a)生成匿名线程,并b)调用同步时,在该同步中按下“enter”键,它会持续添加每个“enter”键按下的“end;”。 - Jerry Dodge
@JerryDodge 我归咎于我目前所在的网络连接(巴厘岛) :-) - Dave Nottage
@AndreasRejbrand 的确,我在看到你的评论之前发表了我的评论。这也让我感到疯狂。我将换行符复制到剪贴板上,然后根据需要粘贴。 - Jerry Dodge
2个回答

8

这是IDE中的一个错误吗?

是的,这是一个缺陷。请提交报告到Quality Portal。


3

这是IDE中的一个错误吗?

是的,这是IDE中的一个错误。您的代码在语法上是有效的。

我该如何修复这个问题?

避免这种情况的最好方法是创建您的代码并用 try...except... 包装它以处理任何异常:

  try
    MyClass := TComponent.Create(Self);
    try

    finally
      MyClass.Free;
    end;
  except on E: Exception do
  end;

那么你的代码将会是这样的:
  TTask.Run(procedure
            var
              client: TIdHTTP;
              result: string;
            begin
              try
                Client := TIdHTTP.Create(nil);
                try
                  client.ReadTimeout := 4000;
                  client.ConnectTimeout := 4000;
                  result := client.Get('a valid url here just as test');
                  TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(result);
                                           end);
                finally
                  Client.Free;
                end;
              except on E: Exception do
                begin
                  TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(E.Message);
                                           end);
                  end;
              end;
            end;

1
我曾认为最终必须始终将所有内容包含在内,但似乎除外的部分被排除了。尝试了一下,它起作用了! - Rosanna Trevisan
7
对我而言,它仍然感觉像是一个 IDE 的 bug。提问者原始代码在语法上是完全有效的。 - Andreas Rejbrand
1
可能警告是关于在Client := TIdHTTP.Create(nil);之前发生异常,变量Client将永远不会被使用的事实。但我仍然认为这可能是一个错误! - Alberto Miola
1
将finally块和except块互换位置只是一种权宜之计,而不是解决方案,也不是每个人都能逃避的。在异常中,使用情况可能需要在finally块中释放的对象仍然有效。如果问题频繁发生,仍然可能是一个bug。 - Graymatter
3
对我来说也一样,这是一个IDE的bug。而且是相当恼人的一个bug。 - Rudy Velthuis
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接