gpt4 book ai didi

multithreading - 在长时间任务期间保持应用程序响应

转载 作者:行者123 更新时间:2023-12-03 15:15:18 25 4
gpt4 key购买 nike

我们应用程序中的某个表单显示模型的图形 View 。用户可以在许多其他事情中发起模型转换,这可能需要相当长的时间。这种转换有时无需任何用户交互即可进行,有时则需要频繁的用户输入。当它持续时,除非需要用户输入,否则 UI 应被禁用(仅显示进度对话框)。

可能的方法:

  1. 忽略该问题,只需将转换代码放入过程中并调用即可。不好,因为在转换需要一些时间但不需要用户输入的情况下,应用程序似乎挂起。
  2. 在代码中添加回调:这很烦人 - 您必须在转换代码中放置很多这些调用 - 而且不可预测 - 您永远无法确定自己会这样做找到了正确的地点。
  3. 在代码中添加 Application.ProcessMessages:与回调相同的问题。此外,您还会遇到 ProcessMessages 的所有问题。
  4. 使用线程:这使我们摆脱了 2. 和 3 中“烦人且不可预测”的部分。然而,由于用户输入需要“编码”,所以工作量很大 - 调用 Synchronize,将任意内容放入定制记录中需要的参数等。调试起来也是一场噩梦,而且容易出错。

//编辑:我们当前的解决方案是线程。然而,由于用户输入,这是一个令人痛苦的事情。而且很多例程中可能有很多输入代码。这让我感觉线程不是正确的解决方案。

我要让自己难堪,并发布我所生成的 GUI 和工作代码的邪恶组合的概述:

type
// Helper type to get the parameters into the Synchronize'd routine:
PGetSomeUserInputInfo = ^TGetSomeUserInputInfo;
TGetSomeUserInputInfo = record
FMyModelForm: TMyModelForm;
FModel: TMyModel;
// lots of in- and output parameters
FResult: Boolean;
end;

{ TMyThread }

function TMyThread.GetSomeUserInput(AMyModelForm: TMyModelForm;
AModel: TMyModel; (* the same parameters as in TGetSomeUserInputInfo *)): Boolean;
var
GSUII: TGetSomeUserInputInfo;
begin
GSUII.FMyModelForm := AMyModelForm;
GSUII.FModel := AModel;
// Set the input parameters in GSUII

FpCallbackParams := @GSUII; // FpCallbackParams is a Pointer field in TMyThread
Synchronize(DelegateGetSomeUserInput);
// Read the output parameters from GSUII
Result := GSUII.FResult;
end;

procedure TMyThread.DelegateGetSomeUserInput;
begin
with PGetSomeUserInputInfo(FpCallbackParams)^ do
FResult := FMyModelForm.DoGetSomeUserInput(FModel, (* the params go here *));
end;

{ TMyModelForm }

function TMyModelForm.DoGetSomeUserInput(Sender: TMyModel; (* and here *)): Boolean;
begin
// Show the dialog
end;

function TMyModelForm.GetSomeUserInput(Sender: TMyModel; (* the params again *)): Boolean;
begin
// The input can be necessary in different situations - some within a thread, some not.
if Assigned(FMyThread) then
Result := FMyThread.GetSomeUserInput(Self, Sender, (* the params *))
else
Result := DoGetSomeUserInput(Sender, (* the params *));
end;

你有什么意见吗?

最佳答案

我认为,只要您的长时间运行的转换需要用户交互,您就不会真正对得到的任何答案感到满意。那么让我们先回顾一下:为什么需要中断转换并请求更多信息?这些问题真的是您在开始转型之前无法预料到的吗?用户肯定也对中断不太满意,对吗?他们不能只是开始转型,然后去喝杯咖啡;而是要这样做。他们需要坐下来观察进度条,以防出现问题。呃。

也许转型遇到的问题是可以“保存”到最后的东西。转换是否需要立即知道答案,还是可以完成其他所有事情,然后再做一些“修复”?

关于multithreading - 在长时间任务期间保持应用程序响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/436524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com