素手执棋 發表於 2019-8-7 08:05:00

TThread.Queue和TThread.Synchronize的区别

<p>TThread.Queue和TThread.Synchronize的区别</p>
<p>效果上:二者的作用都是让业务代码在主线程中执行,差别: Synchronize是阻塞,Queue是非阻塞</p>
<div>
<div>代码上&nbsp;两个方法最终都是调用的&nbsp;class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False)类方法,</div>
<div>差别</div>
<div>Synchronize则是使用了Thread对象中的FSynchronize对象变量,然后QueueEvent为False来调用TThread.Synchronize类方法,&nbsp;</div>
<div>内部在执行FSynchronize时,创建了事件对象,通过WaitForSingleObject来阻塞执行。&nbsp;</div>
<div>Queue调用是自己创建了一个PSynchronizeRecord, 然后QueueEvent为True来调用TThread.Synchronize类方法,内部则把PSynchronizeRecord放入SyncList列表中,然后退回,并不直接执行PSynchronizeRecord, 那问题来了,在那里执行呢?Delphi在TApplication.Idle方法中执行(最终调用了CheckSynchronize)</div>
<div>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">procedure TForm1.OnReceived(Sender: TObject; AConnection: ICrossConnection; ABuf: Pointer; ALen: Integer);
begin
TThread.Queue(nil,
    procedure
    begin
      var ms: tstream := TMemoryStream.Create;
      ms.Size := ALen;
      ms.Write(ABuf^, ALen);
      ms.Position := 0;
      var ms2: tstream := TMemoryStream.Create;
      tzip.UnZipStream(ms, ms2);    //unzip
      ms.Free;
      ms2.Position := 0;
      var pack: tmsgpack := TMsgPack.Create;
      pack.DecodeFromStream(ms2);
      case pack.Force('cmd').AsInteger of
      cmd_query:
          begin
            form1.ClientDataSet1.Data := pack.Force('dataset1').AsVariant;
            form1.ClientDataSet2.Data := pack.Force('dataset2').AsVariant;
          end;
      end;
      pack.Free;
    end);
end;
</pre>
</div>
<p>  </p>
</div>
</div>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/11312934.html</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/11312934.html
頁: [1]
查看完整版本: TThread.Queue和TThread.Synchronize的区别