- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
创建一个 VCL 表单应用程序,在表单上放置一个 TButton 和一个 TMemo,然后在按钮的 OnClick 处理程序中编写以下代码:
uses
OtlParallel, OtlTaskControl;
procedure TForm2.btnStartLoopClick(Sender: TObject);
var
starttime: Cardinal;
k: Integer;
begin
mmoTest.Lines.Clear;
for k := 1 to 50 do
mmoTest.Lines.Add('Line ' + IntToStr(k));
starttime := GetTickCount;
Parallel.Async(
procedure
var
i: Integer;
begin
for i := 1 to 50 do
begin
Sleep(100);
mmoTest.Lines[i - 1] := mmoTest.Lines[i - 1] + FormatDateTime(' nn:ss:zzz', Now);
end;
end,
Parallel.TaskConfig.SetPriority(TOTLThreadPriority.tpHighest).OnTerminated(
procedure
begin
mmoTest.Lines.Add(IntToStr(GetTickCount - starttime) + ' milliseconds');
end));
end;
现在运行程序并进行测试:
点击按钮,只需等待循环完成,然后查看备忘录最后一行显示的时间:应该约为 5300 毫秒。
现在再次单击按钮,单击并按住表单的标题栏并快速移动表单,直到循环完成。现在再看一下备忘录的最后一行: 在我的测试中,时间超过 7000 毫秒。显然,主线程阻塞了并行线程!
那么如何避免主线程阻塞并行线程呢?
最佳答案
首先,此代码不是线程安全的,因为异步代码直接从主 UI 线程之外的任务线程访问 TMemo
。你不能这样做。工作线程必须与 UI 线程同步才能安全地访问 UI 控件,否则可能会发生不好的事情。您可以使用TThread.Synchronize()
, TThread.Queue()
,或IOmniTask.Invoke()
用于同步。
其次,当您在标题栏上按住鼠标时,主 UI 消息循环将被阻止(操作系统正在运行一个单独的模式消息循环,直到您松开鼠标为止)。因此,任务的 OnTerminate 事件处理程序可能不会运行,直到主消息循环重新获得控制权。这可以解释为什么您的计时器持续时间据报告比预期长,而不是因为任务循环被阻止。
第三,Sleep()
不是绝对的。它将休眠至少所请求的时间,但可能休眠更长时间。因此,您的任务循环将运行至少 5 秒,但可能会更长一点。
关于multithreading - 主线程阻塞并行线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41474961/
有人可以向我澄清主线 DHT 规范中的声明吗? Upon inserting the first node into its routing table and when starting up th
我正在尝试使用 USB 小工具驱动程序使嵌入式设备作为 MTP 设备工作。 我知道 Android 从大容量存储设备切换到 MTP 设备已经有一段时间了,并且找到了 source code for M
我是一名优秀的程序员,十分优秀!