Author: h.mohri
When considering migration from old C++Builder 10.2 Tokyo bcc32 project.
You can use functions such as TThread::CreateAnonymousThread()
and TTask to improve performance.
In addition to TCriticalSection, you can also use System.TMonitor which supports multiple devices.
I will show you how to program bcc32 project using the above method.
Table of Contents
TQueue<String>
is created in Delphi.
TQueue<T>
is in System::Generics::Collections
.
To use TQueue<String>
, describe it in Delphi as follows.
1 2 3 4 5 |
<span class="synStatement" style="color:#d88a17;">uses</span> System.Generics.Collections; <span class="synStatement" style="color:#d88a17;">type</span> TQueStr = class(TQueue<<span class="synType" style="color:#3ec63e;">String</span>>) <span class="synStatement" style="color:#d88a17;">end</span>; |
You can now use TQueue__1<System::UnicodeString>
.
Create a class to run in the interior of the TTask
.
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 31 32 33 34 35 36 37 38 39 40 41 |
<span class="synComment" style="color:#4f80e5;">//_proc is a struct to execute TTask::start().</span> <span class="synType" style="color:#3ec63e;">struct</span> _proc: TCppInterfacedObject<TProc> { TQueue__1<System::UnicodeString>* f_queue_; TObject* f_mutex_; <span class="synComment" style="color:#4f80e5;">//TObject behaves like a mutex.</span> <span class="synType" style="color:#3ec63e;">int</span> f_number; _proc(<span class="synType" style="color:#3ec63e;">int</span> i, TObject* lmtx, TQueue__1<System::UnicodeString>* lq):TCppInterfacedObject<TProc>(){ f_mutex_ = lmtx; f_queue_ = lq; f_number = i; <span class="synComment" style="color:#4f80e5;">//This is the number where the Task is executed.</span> } <span class="synComment" style="color:#4f80e5;">//Convert from int to string.</span> std::string int_to_string(<span class="synType" style="color:#3ec63e;">const</span> <span class="synType" style="color:#3ec63e;">int</span> i) { std::ostringstream ss; ss << i; <span class="synStatement" style="color:#d88a17;">return</span> ss.str(); } <span class="synComment" style="color:#4f80e5;">//Executed in TTask.</span> <span class="synType" style="color:#3ec63e;">void</span> __fastcall Invoke(){ std::string s = <span class="synConstant" style="color:#ff6666;">"TTask"</span> + int_to_string(f_number+<span class="synConstant" style="color:#ff6666;">1</span>); <span class="synComment" style="color:#4f80e5;">//Lock with TMonitor.</span> System::TMonitor::Enter(f_mutex_); <span class="synStatement" style="color:#d88a17;">try</span> { <span class="synComment" style="color:#4f80e5;">//Add a character to the common TQueue<String>.</span> f_queue_->Enqueue(s.c_str()); <span class="synComment" style="color:#4f80e5;">//Sleep(100);</span> } __finally { <span class="synComment" style="color:#4f80e5;">//UnLock with TMonitor.</span> System::TMonitor::Exit(f_mutex_); } } <span class="synType" style="color:#3ec63e;">inline</span> __fastcall <span class="synType" style="color:#3ec63e;">virtual</span> ~_proc(<span class="synType" style="color:#3ec63e;">void</span>){ } }; |
Actually executed is void __fastcall Invoke(){}
.
The internal in the task memory each other will use the System::TMonitor::Enter(f_mutex_);
so as not to conflict.
It is a class that creates many TTask
s.
We have created and stored many TTask
s in std::vector<_di_ITask>
.
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 31 |
<span class="synType" style="color:#3ec63e;">struct</span> _queue_task { TQueue__1<System::UnicodeString>* f_queue; TObject* f_mutex; <span class="synComment" style="color:#4f80e5;">//TObject behaves like a mutex.</span> std::vector<_di_ITask> v1; <span class="synComment" style="color:#4f80e5;">//_di_ITask is managed with std::vector.</span> _queue_task(){ f_queue = <span class="synStatement" style="color:#d88a17;">new</span> TQueue__1<System::UnicodeString>(); f_mutex = <span class="synStatement" style="color:#d88a17;">new</span> TObject(); } std::vector<_di_ITask>& start(<span class="synType" style="color:#3ec63e;">const</span> <span class="synType" style="color:#3ec63e;">int</span> icount) { <span class="synComment" style="color:#4f80e5;">// Only the number of purpose, to create a TTask.</span> <span class="synStatement" style="color:#d88a17;">for</span> (<span class="synType" style="color:#3ec63e;">int</span> li = <span class="synConstant" style="color:#ff6666;">0</span>; li < icount; li++) { <span class="synComment" style="color:#4f80e5;">//The TTask is _proc::Invoke() is executed.</span> v1.push_back(TTask::Create(_di_TProc( <span class="synStatement" style="color:#d88a17;">new</span> _proc(li, f_mutex, f_queue)))); } <span class="synStatement" style="color:#d88a17;">for</span> (std::vector<_di_ITask>::iterator tsk = v1.begin(); tsk != v1.end(); ++tsk) { <span class="synComment" style="color:#4f80e5;">//Start the TTask in the std::vector in order.</span> (*tsk)->Start(); } <span class="synStatement" style="color:#d88a17;">return</span> v1; } <span class="synType" style="color:#3ec63e;">virtual</span> ~_queue_task() { <span class="synComment" style="color:#4f80e5;">//Destructor</span> <span class="synStatement" style="color:#d88a17;">delete</span> f_queue; <span class="synStatement" style="color:#d88a17;">delete</span> f_mutex; } }; |
Using TThread::CreateAnonymousThread()
etc., the design method as shown below is also possible.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition