TComponent::BeginInvoke - C++ Builder

C++ Builder 参考手册 ➙ TComponent ➙ BeginInvoke


头文件:#include
命名空间:System::Classes
类:TComponent
访问权限:public:
函数原型:

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const System::Sysutils::_di_TProc AProc, 
    System::TObject *const AContext = NULL);

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const TAsyncProcedureEvent AProc, 
    System::TObject *const AContext = NULL);

template System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const System::DelphiInterface > AFunc, 
    System::TObject *const AContext = NULL);

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const _di_TAsyncConstArrayProc AProc, 
    const System::TVarRec *Params, 
    const int Params_High, 
    System::TObject *const AContext = NULL);

template System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const System::DelphiInterface > AFunc, 
    const System::TVarRec *Params, 
    const int Params_High, 
    System::TObject* const AContext = NULL);

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const TAsyncConstArrayProcedureEvent AProc, 
    const System::TVarRec *Params, 
    const int Params_High, 
    System::TObject *const AContext = NULL);

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const TAsyncConstArrayFunctionEvent AFunc, 
    const System::TVarRec *Params, 
    const int Params_High, 
    System::TObject *const AContext = NULL);

System::Types::_di_IAsyncResult __fastcall BeginInvoke(
    const TAsyncFunctionEvent AFunc, 
    System::TObject *const AContext = NULL);

System::Classes::TComponent::BeginInvoke 是 System::Classes::TComponent 的成员函数,异步调用 AProc 或 AFunc。

参数:

AProc:要异步调用执行的函数,这是没有返回值的函数;
AFunc:要异步调用执行的函数,这是有返回值的函数,函数的返回值并不是通过 return 返回的,而是返回给参数 Result,这是 System::TObject 指针的引用参数;
AContext:要传递给 AProc 或 AFunc 的参数,在 AProc 或 AFunc 里面,通过函数的参数 ASyncResult->AsyncContext 获取 AContext;

返回值:
IAsyncResult 类型的异步执行的结果。

  • 异步调用 AProc 或 AFunc。
  • 如果是从 TControl 继承的,执行在最近创建的窗口句柄所在的线程,否则在主线程里面执行。

例:在 TMyThread 线程里面:

  • 读取 Form1 的 Edit1 编辑框的内容到 sEditText 里面:
    让函数 ReadEdit 在主线程里面异步执行,在主线程里面运行可以处理界面(读取编辑框的内容);
  • 再把 sEditText 的内容输出到 Form1 的 Memo1 里面:
    让函数 OutputText 在主线程里面异步执行,在主线程里面运行可以处理界面(把数据输出到 Memo1)。
  • TMyContext 为函数传递的参数;TMyResult 为函数的返回值。
class TMyContext : public System::TObject
{
public:
    DWORD dwCallerID;
    UnicodeString sTextToDisplay;
    UnicodeString sErrorMessage;
    __fastcall TMyContext(){ dwCallerID = 0; }
};

class TMyResult : public System::TObject
{
public:
    UnicodeString sEditText;
};

class TMyThread : public System::Classes::TThread
{
private:
    void __fastcall ReadEdit(const System::Types::_di_IAsyncResult ASyncResult, System::TObject *&Result);
    void __fastcall OutputText(const System::Types::_di_IAsyncResult ASyncResult);
protected:
    void __fastcall Execute(void);
public:
    __fastcall TMyThread();
};

__fastcall TMyThread::TMyThread()
    : TThread(true)
{
}

void __fastcall TMyThread::ReadEdit(const System::Types::_di_IAsyncResult ASyncResult, System::TObject *&Result)
{
    Result = NULL;
    UnicodeString sEdTxt;

    TMyContext *lpMyCt = dynamic_cast(ASyncResult->GetAsyncContext());
    if(lpMyCt)
    {
        sEdTxt = Form1->Edit1->Text;

        UnicodeString sMsg;
        DWORD dwThreadID = ::GetCurrentThreadId();
        sMsg.cat_sprintf(L"读取编辑框内容 = \"%s\"\r\n", sEdTxt.c_str());
        sMsg.cat_sprintf(L"当前函数的线程ID = %lu\r\n", dwThreadID);
        sMsg.cat_sprintf(L"调用函数的线程ID = %lu\r\n", lpMyCt->dwCallerID);
        Form1->Memo1->Lines->Add(sMsg);
    }

    TMyResult *r = new TMyResult;
    r->sEditText = sEdTxt;
    Result = r;
}

void __fastcall TMyThread::OutputText(const System::Types::_di_IAsyncResult ASyncResult)
{
    TMyContext *lpMyCt = dynamic_cast(ASyncResult->GetAsyncContext());
    if(lpMyCt)
    {
        UnicodeString sMsg;
        DWORD dwThreadID = ::GetCurrentThreadId();
        sMsg.cat_sprintf(L"输出编辑框内容 = \"%s\"\r\n", lpMyCt->sTextToDisplay.c_str());
        sMsg.cat_sprintf(L"当前函数的线程ID = %lu\r\n", dwThreadID);
        sMsg.cat_sprintf(L"调用函数的线程ID = %lu\r\n", lpMyCt->dwCallerID);
        Form1->Memo1->Lines->Add(sMsg);
    }
}

void __fastcall TMyThread::Execute(void)
{
    UnicodeString sEditText;

    TMyContext *lpMyCt =new TMyContext;
    lpMyCt->dwCallerID = ::GetCurrentThreadId();

    System::Types::_di_IAsyncResult aResult;
    aResult = Form1->BeginInvoke(ReadEdit, lpMyCt);

    try
    {
//      Form1->EndInvoke(aResult);
        TObject *lpInvokeResult = Form1->EndFunctionInvoke(aResult);
        TMyResult *lpMyResult = dynamic_cast(lpInvokeResult);
        if(lpMyResult)
        {
            sEditText = lpMyResult->sEditText;
            delete lpMyResult;
        }
    }
    catch(Exception &e)
    {
        lpMyCt->sErrorMessage = e.Message;
    }

    lpMyCt->sTextToDisplay = sEditText;
    aResult = Form1->BeginInvoke(OutputText, lpMyCt);

    try
    {
        Form1->EndInvoke(aResult);
    }
    catch(Exception &e)
    {
    }

    delete lpMyCt;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    DWORD dwThreadID = ::GetCurrentThreadId();
    UnicodeString sMsg;
    sMsg.sprintf(L"主线程ID = %lu\r\n", dwThreadID);
    Memo1->Lines->Add(sMsg);

    TMyThread *lpThread = new TMyThread;
    lpThread->FreeOnTerminate = true;
    lpThread->Start();
}

运行结果:

运行结果:在主线程里面运行 BeginInvoke 函数的线程

参考:

  • System::Classes::TComponent::EndInvoke
  • System::Classes::TComponent::EndFunctionInvoke
  • System::Classes::TComponent::Invoke
  • System::Classes::TThread::Synchronize
  • System::Syncobjs::TCriticalSection
  • System::Classes::TComponent
  • System::Classes::TPersistent
  • System::TObject
  • VCL 类继承关系

C++ Builder 参考手册 ➙ TComponent ➙ BeginInvoke

你可能感兴趣的:(TComponent::BeginInvoke - C++ Builder)