{"id":5683,"date":"2023-07-22T10:14:56","date_gmt":"2023-07-22T02:14:56","guid":{"rendered":"https:\/\/blog.qdac.cc\/?p=5683"},"modified":"2023-07-22T10:14:57","modified_gmt":"2023-07-22T02:14:57","slug":"%e6%95%99%e7%a8%8b%e9%ab%98%e6%95%88%e5%a4%84%e7%90%86%e5%9c%a8%e4%b8%bb%e7%ba%bf%e7%a8%8b%e4%b8%ad%e6%98%be%e7%a4%ba%e5%90%8e%e5%8f%b0%e7%ba%bf%e7%a8%8b%e5%a4%84%e7%90%86%e8%bf%9b%e5%ba%a6","status":"publish","type":"post","link":"https:\/\/blog.qdac.cc\/?p=5683","title":{"rendered":"[\u6559\u7a0b]\u9ad8\u6548\u5904\u7406\u5728\u4e3b\u7ebf\u7a0b\u4e2d\u663e\u793a\u540e\u53f0\u7ebf\u7a0b\u5904\u7406\u8fdb\u5ea6"},"content":{"rendered":"\n<p>\u5148\u770b\u7ecf\u5178\u7684\u5904\u7406\u65b9\u6cd5\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TThread.CreateAnonymousThread(\n    procedure\n    var\n      AHint: TZProgressNotify;\n      ACount: Integer;\n      ATime: Cardinal;\n    const\n      PassCount=1000000;\n    begin\n      ACount := 0;\n      ATime := TThread.GetTickCount;\n      while (not Application.Terminated) and (ACount &lt; PassCount) do\n      begin\n        AHint.Progress := ACount*100 div PassCount ;\n        AHint.HintText := ACount.ToString;\n        Inc(ACount);\n        <strong>TThread.Synchronize(nil,\n          procedure\n          begin\n            FProgress.Update(AHint);\n          end\n        );<\/strong>\n        FProgress.Update(AHint);\n      end;\n      AHint.HintText := (TThread.GetTickCount - ATime).ToString + 'ms';\n      FProgress.Update(AHint);\n    end).Start;<\/code><\/pre>\n\n\n\n<p>\u6211\u4eec\u9700\u8981\u66f4\u65b0\u8fdb\u5ea6\u65f6\uff0c\u5c06\u5176\u5207\u6362\u5230\u4e3b\u7ebf\u7a0b\uff0c\u5e76\u66f4\u65b0\u8fdb\u5ea6\u663e\u793a\u3002\u6211\u4eec\u6d4b\u8bd5\u663e\u793a\u7528\u4e8632735ms\uff0c\u4e5f\u5c31\u662f\u8bf4100\u4e07\u6b21\u8fdb\u5ea6\u66f4\u65b0\uff0c\u7528\u4e86\u7ea633\u79d2\u3002<\/p>\n\n\n\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u770b\u4e0b\u4f18\u5316\u540e\u7684\u4ee3\u7801\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TThread.CreateAnonymousThread(\n    procedure\n    var\n      AHint: TZProgressNotify;\n      ACount: Integer;\n      ATime: Cardinal;\n    const\n      PassCount=1000000;\n    begin\n      ACount := 0;\n      ATime := TThread.GetTickCount;\n      while (not Application.Terminated) and (ACount &lt; PassCount) do\n      begin\n        AHint.Progress := ACount*100 div PassCount ;\n        AHint.HintText := ACount.ToString;\n        Inc(ACount);\n        <strong>FProgress.Update(AHint);<\/strong>\n      end;\n      AHint.HintText := (TThread.GetTickCount - ATime).ToString + 'ms';\n      FProgress.Update(AHint);\n    end).Start;<\/code><\/pre>\n\n\n\n<p>\u5bf9\u7684\uff0c\u4f60\u6ca1\u770b\u9519\uff0c\u6211\u4eec\u5c06 FProgress.Update \u76f4\u63a5\u5728\u540e\u53f0\u7ebf\u7a0b\u8c03\u7528\u4e86\u3002\u6211\u4eec\u5bf9\u5176\u4ee3\u7801\u8fdb\u884c\u4e86\u903b\u8f91\u9694\u79bb\uff0c\u5b9e\u6d4b 100 \u4e07\u6b21\u8fdb\u5ea6\u66f4\u65b0\uff0c\u7528\u65f6 78 \u6beb\u79d2\u3002<\/p>\n\n\n\n<p>\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u5177\u4f53\u7684\u5b9e\u73b0\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>type\n  TZProgressNotify = record\n    Progress: Integer;\n    HintText: String;\n  end;\n\nTZMainThreadUpdator &lt; T: record >= record\nprivate\nconst\n  FLAG_READING = Integer($80000000);\nvar\n  FBuffers: array &#91;0 .. 1] of T;\n  FActiveIndex, FUpdateRefCount: Integer;\npublic\n  procedure Update(const AValue: T);\n  function GetData: T;overload;\n  procedure GetData(var AValue: T);overload;\n  property Data: T read GetData;\nend;\n\n{ TZMainThreadUpdator&lt;T> }\n\nprocedure TZMainThreadUpdator&lt;T>.GetData(var AValue: T);\n\/\/ \u503c\u590d\u5236\u53ef\u80fd\u4f1a\u5f15\u8d77\u51b2\u7a81\uff0c\u6211\u4eec\u9700\u8981\u907f\u514d\u5728\u503c\u590d\u5236\u65f6\uff0c\u5916\u90e8\u66f4\u65b0\uff0c\u6240\u4ee5\u5c06 FActiveIndex \u52a0\u5165\u6807\u5fd7\u4f4d\nvar\n  ABufferIndex: Integer;\nbegin\n  Assert(MainThreadId = TThread.Current.ThreadID,\n    'GetData must invoke in main thread');\n  \/\/\u8bbe\u7f6e\u8bfb\u53d6\u4e2d\u6807\u8bb0\u4f4d\uff0c\u8bbe\u7f6e\u540e\uff0cUpdate\u4e0d\u4f1a\u66f4\u65b0 FActiveIndex \u7684\u503c\n  repeat\n    ABufferIndex := FActiveIndex;\n  until AtomicCmpExchange(FActiveIndex, ABufferIndex or FLAG_READING,\n    ABufferIndex) = ABufferIndex;\n  AValue := FBuffers&#91;ABufferIndex];\n  \/\/\u5141\u8bb8\u540e\u7eed\u7684 Update \u66f4\u65b0 FActiveIndex \u7684\u503c\u4ee5\u4f53\u73b0\u6700\u65b0\u7684\u8fdb\u5ea6\n  AtomicExchange(FActiveIndex, ABufferIndex);\nend;\n\nfunction TZMainThreadUpdator&lt;T>.GetData: T;\nbegin\n  GetData(Result);\nend;\n\nprocedure TZMainThreadUpdator&lt;T>.Update(const AValue: T);\nvar\n  ABufferIndex: Integer;\nbegin\n  ABufferIndex := AtomicIncrement(FUpdateRefCount);\n  try\n    \/\/ \u589e\u52a0\u8ba1\u6570\uff0c\u5982\u679c\u6709\u591a\u4e2a\u540c\u65f6\u63d0\u4ea4\u66f4\u65b0\uff0c\u53ea\u6709\u7b2c\u4e00\u4e2a\u4f1a\u4fdd\u7559\uff0c\u5269\u4e0b\u7684\u4f1a\u4e22\u5f03\n    if ABufferIndex = 1 then\n    begin\n      \/\/ \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u66f4\u65b0\uff0c\u53ea\u4fdd\u7559\u7b2c\u4e00\u4e2a\u66f4\u65b0\u7ebf\u7a0b\u7684\u7ed3\u679c\uff0c\u907f\u514d\u4f7f\u7528\u9501\n      ABufferIndex := (FActiveIndex + 1) and $1;\n      FBuffers&#91;ABufferIndex] := AValue;\n      \/\/ \u5982\u679c FActiveIndex \u4e0d\u5904\u4e8e\u8bfb\u72b6\u6001\uff0c\u5219\u66f4\u65b0\uff0c\u5426\u5219\u5ffd\u7565\u66f4\u65b0\uff0c\u53ef\u4ee5\u589e\u52a0\u989d\u5916\u7684\u6807\u8bb0\u6765\u8bb0\u5f55\u8fd9\u4e2a\u60c5\u51b5\uff0c\u7136\u540e\u5728\u8bfb\u53d6\u7684\u65f6\u5019\u6e05\u695a\u8fd9\u4e00\u6807\u8bb0\uff0c\u672c\u7248\u672c\u4e0d\u505a\u5904\u7406\n      AtomicCmpExchange(FActiveIndex, ABufferIndex, FActiveIndex and $1);\n    end;\n  finally\n    AtomicDecrement(FUpdateRefCount);\n  end;\nend;\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u5148\u770b\u7ecf\u5178\u7684\u5904\u7406\u65b9\u6cd5\uff1a \u6211\u4eec\u9700\u8981\u66f4\u65b0\u8fdb\u5ea6\u65f6 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[8],"tags":[],"class_list":["post-5683","post","type-post","status-publish","format-standard","hentry","category-delphi"],"views":2396,"_links":{"self":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/5683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5683"}],"version-history":[{"count":4,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/5683\/revisions"}],"predecessor-version":[{"id":5687,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/5683\/revisions\/5687"}],"wp:attachment":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}