Raf*_*ssi 14 delphi multithreading
我正在网上阅读Nick Hodges,我发现了Queue,但它并没有像我预期的那样表现,我无法理解他和文档所说的内容.看看这段代码:
TThread.CreateAnonymousThread(
procedure
begin
TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('start');
end);
Sleep(2000);
TThread.Synchronize(TThread.Current, procedure
begin
Memo1.Lines.Add('end');
end);
end
).Start;
Run Code Online (Sandbox Code Playgroud)
我总是使用,Synchronize但这次我尝试过,Queue因为根据尼克,在多个请求的情况下更好,因为它们不会被"序列化"并逐个执行.上面的代码工作正常.为什么这不起作用呢?
TThread.CreateAnonymousThread(
procedure
begin
TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('start');
end);
Sleep(2000);
TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Add('end');
end);
end
).Start;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,备注输出start但不是结束.我打电话的时候:
start备忘录中的内容Rik*_*Rik 19
queue和synchronize之间的区别在于Synchronize()将调用放入队列并等待该调用完成Queue()并将调用放入队列并直接将控制返回给线程.
但是...... 官方文档中没有提到这一点,当一个线程完成时,队列中的所有调用都被删除Queue(AThread, AMethod),其中AThread是自己的线程.
您可以清楚地看到在TThread.Destroy()哪里RemoveQueuedEvents(Self)调用.
RemoveQueuedEvents删除排队的方法调用.[...]如果指定了AThread,则删除此线程排队的所有方法调用.
因此,在您的最后一个Queue()线程结束后直接TThread.Destroy()执行,并且从队列中删除最后一个调用.
您可以采取一些措施来解决这个问题.
TThread.Queue(nil, AMethod).BTW调用TThread.Queue(AMethod)是相同的,TThread.Queue(Self, AMethod)所以如果线程即将结束并且您希望调用完成,您将始终需要使用nil-variant.Synchronize()最后一个队列方法来完成此操作.请注意,最后一次同步不必是真正的过程.您可以在TThread.Execute类似的结尾处调用同步到虚拟过程Synchronize(DummySync)(示例).队列如果是FIFO,那么线程将等待直到队列中的所有调用都被处理(包括空dummysync).可以在这些页面上找到一些额外的信息
确保在线程自毁之前完成所有TThread.Queue方法
http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/
| 归档时间: |
|
| 查看次数: |
5730 次 |
| 最近记录: |