【问题标题】:Try..Except ignored inside a thread尝试..除了在线程内被忽略
【发布时间】:2022-01-12 01:18:47
【问题描述】:

我有一个基本的try..except 可以在尝试将PNG 文件加载到TImage 时捕获错误:

try
  Previewimage.Picture.LoadFromFile(filename);
except
  //code to handle exception
end;

如果文件不存在,或者在我的情况下 PNG 已损坏,这通常可以正常工作。我无法控制PNG的源代码创建,因此需要捕获无法加载PNG的时间,即它给出了错误:

此“便携式网络图形”图像无效,因为它包含无效的数据片段(crc 错误)。

我的问题是 try..except 在工作线程中。这似乎会导致 try..except 被忽略,并且我的程序因 CRC 异常而崩溃。

这个问题有什么简单的解决办法吗?

【问题讨论】:

  • TImage 是一个可视化组件,这意味着它与主线程有亲和性,不能从后台线程进行操作。
  • 它可以并且每次都愉快地更新,除非 PNG 已损坏。我了解线程和尝试更新显示的多个线程的可能问题可能会导致问题,但这严格来说只是一个线程。
  • 不,它不是单个线程——如果您从主线程以外的线程调用此代码(您说您是),则不会。没有办法让访问可视化组件线程安全 - 例如,主线程可能会在您在另一个线程中覆盖它的同时尝试绘制图像,并且没有内置机制允许您同步此类访问。当然,它看起来可以工作,但这并不意味着它以后不会随机失败 - 如果它工作,它是靠运气工作的,而不是设计的。
  • 至于其余的,我们需要查看您的实际代码。你的代码在except 块中做什么?在这里提供minimal reproducible example 应该很简单。 try/except 绝对可以在线程中工作,所以你正在做的其他事情会导致它失败。很可能您正在 except 块中执行某些操作,该块本身在捕获第一个异常后会引发第二个异常。考虑安装和使用 MadExcept 等调试工具。
  • 好的,那么使该线程安全的最佳方法是什么?如何告诉主线程尝试在调用线程之外加载 PNG 文件? MadExcpet 也直接指向 LoadFromFIle 调用,给出了我报告的错误。

标签: delphi png vcl timage


【解决方案1】:

异常和try..except 块在工作线程中工作得很好。但是在没有正确同步的情况下访问 UI 控件可能会导致各种问题。所以不要这样做。

在工作线程的上下文中,使用本地TPicture 对象或更好的TPNGImage 对象加载PNG 文件,然后使用TThread.Synchronize()TThread.Notify()Assign() 将该对象到@987654327 @在主线程的上下文中,例如:

try
  PNG := TPNGImage.Create;
  try
    PNG.LoadFromFile(filename);
    TThread.Synchronize(nil,
      procedure
      begin
        Previewimage.Picture.Assign(PNG);
      end
    );
  finally
    PNG.Free;
  end;
except
  //code to handle exception
end; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2016-01-01
    • 2020-02-24
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多