How to enqueue TQueue from TTask with bcc32

by Oct 3, 2017

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.

TQueue<String> is created in Delphi.

TQueue<T> is in System::Generics::Collections.
To use TQueue<String>, describe it in Delphi as follows.

  TQueStr = class(TQueue<String>)

You can now use TQueue__1<System::UnicodeString>.

Create a class to run in the interior of the TTask.

//_proc is a struct to execute TTask::start().
struct _proc: TCppInterfacedObject<TProc>
    TQueue__1<System::UnicodeString>* f_queue_;
    TObject* f_mutex_;      //TObject behaves like a mutex.
    int f_number;

    _proc(int i, TObject* lmtx, TQueue__1<System::UnicodeString>* lq):TCppInterfacedObject<TProc>(){
        f_mutex_ = lmtx;
        f_queue_ = lq;
        f_number = i;       //This is the number where the Task is executed.

    //Convert from int to string.
    std::string int_to_string(const int i)
        std::ostringstream ss;
        ss << i;
        return ss.str();

    //Executed in TTask.
    void __fastcall Invoke(){
        std::string s = "TTask" + int_to_string(f_number+1//Lock with TMonitor.
            //Add a character to the common TQueue<String>.
            //UnLock with TMonitor.
    inline __fastcall virtual ~_proc(void){

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 TTasks.

We have created and stored many TTasks in std::vector<_di_ITask>.

struct _queue_task
    TQueue__1<System::UnicodeString>* f_queue;
    TObject* f_mutex;           //TObject behaves like a mutex.
    std::vector<_di_ITask> v1;  //_di_ITask is managed with std::vector.
        f_queue = new TQueue__1<System::UnicodeString>();
        f_mutex = new TObject();
    std::vector<_di_ITask>& start(const int icount)
        // Only the number of purpose, to create a TTask.
        for (int li = 0//The TTask is _proc::Invoke() is executed.
            v1.push_back(TTask::Create(_di_TProc( new _proc(li, f_mutex, f_queue))));
        for (std::vector<_di_ITask>::iterator tsk = v1.begin(); tsk != v1.end(); ++tsk)
            //Start the TTask in the std::vector in order.
        return v1;
    virtual ~_queue_task()
        delete f_queue;
        delete f_mutex;

Using TThread::CreateAnonymousThread() etc., the design method as shown below is also possible.