【问题标题】:In C++ Builder, how to execute a function inside a `TThread`?在 C++ Builder 中,如何在 `TThread` 中执行函数?
【发布时间】:2020-05-10 17:18:21
【问题描述】:

我使用File > New > Other > Thread Object 菜单创建了一个TThread。它给了我一些样板代码,如下所示:

//---------------------------------------------------------------------------

#include <System.hpp>
#pragma hdrstop

#include "Unit2.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(&UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall MyThreadClass::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall MyThreadClass::MyThreadClass(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall MyThreadClass::Execute()
{
    NameThreadForDebugging(System::String(L"MyThread"));
    //---- Place thread code here ----
    ShowMessage("Hello World!");
}
//---------------------------------------------------------------------------

标题

//---------------------------------------------------------------------------

#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class MyThreadClass : public TThread
{
protected:
    void __fastcall Execute();
public:
    __fastcall MyThreadClass(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif

我添加了您可以看到的行 ShowMessage("Hello World!"),并运行了程序,但除了显示我的表单之外什么也没有发生。

如何在我的线程函数中执行代码?

【问题讨论】:

  • 你不能在一个线程中ShowMessage()。图形控件(FMX 或 VCL)不是线程安全的。所有可视化控件的使用都必须由主线程自己完成。这记录在您提供的生成源中,位于顶部的大注释块中。您是否阅读了其中的注释和代码示例?
  • 您需要创建您的类的实例才能真正创建线程并运行代码。 someVar = new MyThreadClass(false); 但正如 Ken 所说,调用 ShowMessage 是不安全的。
  • @KenWhite 我知道在某些时候我将不得不使用Synchronize,但我相信我应该先学习如何让TThread 运行。我认为ShowMessage() 应该可以工作,即使它之后会冻结我的程序(基于我之前从单独的非 TThread 线程执行 VCL 的经验)。
  • @GirkovArpa:正如我之前提到的,你不能在线程中使用ShowMessage()。这是一个 GUI 调用,如果没有 Synchronize(或更新版本中的 Queue),您将无法使用 VCL。没有例外。它根本行不通。我再次指出我之前的评论。
  • 来自生成单元顶部的代码注释(强调我的):重要:VCL中对象的方法和属性只能是/ / 用于使用 Synchronize 调用的方法中, 请注意该句子中的 ONLY 一词。 Only 没有歧义。

标签: multithreading c++builder vcl


【解决方案1】:

我不得不用这个替换 ShowMessage("Hello World!") 行:

Synchronize([](){ ShowMessage("Hello World!"); });

并用这个创建线程:

MyThreadClass* myThread = new MyThreadClass(false); // false == don't create suspended

【讨论】:

  • 你的 lambda 应该使用[] 而不是[&amp;],因为它实际上并没有捕获任何东西。此外,RTL 有 TThread::CreateAnonymousThread() 在线程中运行 lambda。此外,Win32 API MessageBox() 是线程安全的,因此您可以使用它而不是 ShowMessage(),这样您就不再需要 Synchronize() 来显示弹出消息了。
猜你喜欢
  • 1970-01-01
  • 2013-08-26
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 2011-02-25
  • 1970-01-01
相关资源
最近更新 更多