Main thread blocking parallel thread?
创建一个 VCL Forms 应用程序,在 Form 上放置一个 TButton 和一个 TMemo,并在按钮的 OnClick 处理程序中编写此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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 线程之外的任务线程访问
其次,当您在标题栏上按住鼠标时,主 UI 消息循环被阻止(操作系统正在运行一个单独的模式消息循环,直到您松开鼠标)。因此,在主消息循环重新获得控制权之前,可能不会运行任务的
第三,