📄 asynccalls.html
字号:
<h2>VCL synchronization</h2>
<p>LocalVclCall() executes the given local function/procedure in the main thread. It
uses the TThread.Synchronize function which blocks the current thread.
LocalAsyncVclCall() execute the given local function/procedure in the main thread.
It does not wait for the main thread to execute the function unless the current
thread is the main thread. In that case it executes and waits for the specified
function in the current thread like LocalVclCall().<br/>
<br/>
The result value of the asynchronous function is returned by IAsyncCall.Sync() and
IAsyncCall.ReturnValue().</p>
<div class="code">
<span class="u5">procedure</span> <span class="u4">LocalVclCall</span><span class="u9">(</span><span class="u4">LocalProc</span><span class="u9">:</span> <span class="u4">TLocalVclProc</span><span class="u9">;</span> <span class="u4">Param</span><span class="u9">:</span> <span class="u4">INT_PTR</span> <span class="u9">=</span> <span class="u6">0</span><span class="u9">);</span>
<br><span class="u5">function</span> <span class="u4">LocalAsyncVclCall</span><span class="u9">(</span><span class="u4">LocalProc</span><span class="u9">:</span> <span class="u4">TLocalVclProc</span><span class="u9">;</span> <span class="u4">Param</span><span class="u9">:</span> <span class="u4">INT_PTR</span> <span class="u9">=</span> <span class="u6">0</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span>
</div>
<h3 class="Example">Example</h3>
<div class="code">
<span class="u5">procedure</span> <span class="u4">TForm1</span><span class="u9">.</span><span class="u4">MainProc</span><span class="u9">;</span>
<br>
<br> <span class="u5">procedure</span> <span class="u4">DoSomething</span><span class="u9">;</span>
<br>
<br> <span class="u5">procedure</span> <span class="u4">UpdateProgressBar</span><span class="u9">(</span><span class="u4">Percentage</span><span class="u9">:</span> <span class="u4">Integer</span><span class="u9">);</span>
<br> <span class="u5">begin</span>
<br> <span class="u4">ProgressBar</span><span class="u9">.</span><span class="u4">Position</span> <span class="u9">:=</span> <span class="u4">Percentage</span><span class="u9">;</span>
<br> <span class="u4">Sleep</span><span class="u9">(</span><span class="u6">20</span><span class="u9">);</span> <span class="u9"></span><span class="u1">// This delay does not affect the time for the 0..100 loop</span>
<br> <span class="u9"></span><span class="u1">// because UpdateProgressBar is non-blocking.</span>
<br> <span class="u5">end</span><span class="u9">;</span>
<br>
<br> <span class="u5">procedure</span> <span class="u4">Finished</span><span class="u9">;</span>
<br> <span class="u5">begin</span>
<br> <span class="u4">ShowMessage</span><span class="u9">(</span><span class="u8">'Finished'</span><span class="u9">);</span>
<br> <span class="u5">end</span><span class="u9">;</span>
<br>
<br> <span class="u5">var</span>
<br> <span class="u4">I</span><span class="u9">:</span> <span class="u4">Integer</span><span class="u9">;</span>
<br> <span class="u5">begin</span>
<br> <span class="u5">for</span> <span class="u4">I</span> <span class="u9">:=</span> <span class="u6">0</span> <span class="u5">to</span> <span class="u6">100</span> <span class="u5">do</span>
<br> <span class="u5">begin</span>
<br> <span class="u9"></span><span class="u1">// Do some time consuming stuff</span>
<br> <span class="u4">Sleep</span><span class="u9">(</span><span class="u6">30</span><span class="u9">);</span>
<br> <span class="u4">LocalAsyncVclCall</span><span class="u9">(@</span><span class="u4">UpdateProgressBar</span><span class="u9">,</span> <span class="u4">I</span><span class="u9">);</span> <span class="u9"></span><span class="u1">// non-blocking</span>
<br> <span class="u5">end</span><span class="u9">;</span>
<br> <span class="u4">LocalVclCall</span><span class="u9">(@</span><span class="u4">Finished</span><span class="u9">);</span> <span class="u9"></span><span class="u1">// blocking</span>
<br> <span class="u5">end</span><span class="u9">;</span>
<br>
<br><span class="u5">var</span>
<br> <span class="u4">a</span><span class="u9">:</span> <span class="u4">IAsyncCall</span><span class="u9">;</span>
<br><span class="u5">begin</span>
<br> <span class="u4">a</span> <span class="u9">:=</span> <span class="u4">LocalAsyncCall</span><span class="u9">(@</span><span class="u4">DoSomething</span><span class="u9">);</span>
<br> <span class="u4">a</span><span class="u9">.</span><span class="u4">ForceDifferentThread</span><span class="u9">;</span> <span class="u9"></span><span class="u1">// Do not execute in the main thread because this will</span>
<br> <span class="u9"></span><span class="u1">// change LocalAyncVclCall into a blocking LocalVclCall</span>
<br> <span class="u9"></span><span class="u1">// do something</span>
<br> <span class="u9"></span><span class="u1">//a.Sync; The Compiler will call this for us in the Interface._Release method</span>
<br><span class="u5">end</span><span class="u9">;</span>
</div>
<p> </p>
<h2>EnterMainThread/LeaveMainThread</h2>
<p>EnterMainThread/LeaveMainThread can be used to temporary switch to the
main thread. The code that should be synchonized (blocking) has to be put
into a try/finally block and the LeaveMainThread() function must be called
from the finally block. A missing try/finally will lead to an access violation.</p>
<div class="code">
<span class="u5">procedure</span> <span class="u4">EnterMainThread</span><span class="u9">;</span>
<br><span class="u5">procedure</span> <span class="u4">LeaveMainThread</span><span class="u9">;</span>
</div>
<ul>
<li>All local variables can be used. (EBP points to the thread's stack while
ESP points the the main thread's stack)</li>
<li>Unhandled exceptions are passed to the surrounding thread.</li>
<li>The integrated Debugger is not able to follow the execution flow. You have
to use break points instead of "Step over/in".</li>
<li>Nested calls to EnterMainThread/LeaveMainThread are ignored. But they must
strictly follow the try/finally structure.</li>
</ul>
<h3 class="Example">Example</h3>
<div class="code">
<span class="u5">procedure</span> <span class="u4">MyThreadProc</span><span class="u9">;</span>
<br><span class="u5">var</span>
<br> <span class="u4">S</span><span class="u9">:</span> <span class="u5">string</span><span class="u9">;</span>
<br><span class="u5">begin</span>
<br> <span class="u4">Assert</span><span class="u9">(</span><span class="u4">GetCurrentThreadId</span> <span class="u9"><></span> <span class="u4">MainThreadId</span><span class="u9">);</span>
<br> <span class="u4">S</span> <span class="u9">:=</span> <span class="u8">'Hallo, I'</span><span class="u8">'m executed in the main thread'</span><span class="u9">;</span>
<br>
<br> <span class="u4">EnterMainThread</span><span class="u9">;</span>
<br> <span class="u5">try</span>
<br> <span class="u4">Assert</span><span class="u9">(</span><span class="u4">GetCurrentThreadId</span> <span class="u9">=</span> <span class="u4">MainThreadId</span><span class="u9">);</span>
<br> <span class="u4">ShowMessage</span><span class="u9">(</span><span class="u4">S</span><span class="u9">);</span>
<br> <span class="u5">finally</span>
<br> <span class="u4">LeaveMainThread</span><span class="u9">;</span>
<br> <span class="u5">end</span><span class="u9">;</span>
<br>
<br> <span class="u4">Assert</span><span class="u9">(</span><span class="u4">GetCurrentThreadId</span> <span class="u9"><></span> <span class="u4">MainThreadId</span><span class="u9">);</span>
<br><span class="u5">end</span><span class="u9">;</span>
</div>
<p> </p>
<h2>AsyncCall functions</h2>
<p>The AsyncCall() functions start a specified asynchronous function.<br/>
The AsyncExec() function calls the IdleMsgMethod in a loop, while the async.
method is executed.</p>
<div class="code">
<span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgObjectProc</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">TObject</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgIntegerProc</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Integer</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgStringProc</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u5">string</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgWideStringProc</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">WideString</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgInterfaceProc</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">IInterface</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgExtendedProc</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Extended</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCallVar</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgVariantProc</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Variant</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgObjectMethod</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">TObject</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgIntegerMethod</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Integer</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgStringMethod</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u5">string</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgWideStringMethod</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">WideString</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgInterfaceMethod</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">IInterface</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgExtendedMethod</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Extended</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCallVar</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgVariantMethod</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Variant</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgObjectEvent</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">TObject</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgIntegerEvent</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Integer</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgStringEvent</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u5">string</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgWideStringEvent</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">WideString</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgInterfaceEvent</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">IInterface</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgExtendedEvent</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Extended</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br><span class="u5">function</span> <span class="u4">AsyncCallVar</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TAsyncCallArgVariantEvent</span><span class="u9">;</span> <span class="u5">const</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">Variant</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
<br/>
<br><span class="u5">procedure</span> <span class="u4">AsyncExec</span><span class="u9">(</span><span class="u4">Method</span><span class="u9">:</span> <span class="u4">TNotifyEvent</span><span class="u9">;</span> <span class="u4">Arg</span><span class="u9">:</span> <span class="u4">TObject</span><span class="u9">;</span> <span class="u4">IdleMsgMethod</span><span class="u9">:</span> <span class="u4">TAsyncIdleMsgMethod</span><span class="u9">);</span>
</div>
<ul>
<li><b>Proc/Method</b>: Function that should be executed asynchron.
<li><b>Arg</b>: User defined argument that is copied to the asynchron function argument.
</ul>
<h3 class="Example">Example</h3>
<div class="code"><span class="u5">function</span> <span class="u4">TestFunc</span><span class="u9">(</span><span class="u5">const</span> <span class="u4">Text</span><span class="u9">:</span> <span class="u5">string</span><span class="u9">):</span> <span class="u4">Integer</span><span class="u9">;</span>
<br><span class="u5">begin</span>
<br> <span class="u4">Result</span> <span class="u9">:=</span> TimeConsumingFuncion<span class="u9">(</span><span class="u4">Text</span><span class="u9">);</span>
<br><span class="u5">end</span><span class="u9">;</span>
<br>
<br><span class="u4">a</span> <span class="u9">:=</span> <span class="u4">AsyncCall</span><span class="u9">(</span><span class="u4">TestFunc</span><span class="u9">,</span> <span class="u8">'A Text'</span><span class="u9">);</span>
</div>
<p> </p>
<h2>AsyncCallEx functions</h2>
<p>The AsyncCallEx() functions start a specified asynchronous function with a referenced value type (record) that can
be manipulated in the asynchron function.</p>
<div class="code">
<span class="u5">function</span> <span class="u4">AsyncCallEx</span><span class="u9">(</span><span class="u4">Proc</span><span class="u9">:</span> <span class="u4">TAsyncCallArgRecordProc</span><span class="u9">;</span> <span class="u5">var</span> <span class="u4">Arg</span><span class="u1">{: TRecordType}</span><span class="u9">):</span> <span class="u4">IAsyncCall</span><span class="u9">;</span> <span class="u5">overload</span><span class="u9">;</span>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -