如何使用 CWinThread 在 MFC 中创建工作线程?

Posted

技术标签:

【中文标题】如何使用 CWinThread 在 MFC 中创建工作线程?【英文标题】:How to Use CWinThread for making worker thread in MFC? 【发布时间】:2012-08-25 16:57:55 【问题描述】:

我想知道在 MFC 中使用 CWinThread 派生类作为工作线程的过程是什么。 msdn 文档说 CWinthread::InitInstance() 或 CWinthread::Run() 应该只用于 UI 线程。

那么除了 AfxbeginThread() 之外,还有其他方法可以创建工作线程吗?我需要在我的代码中有一个工作线程类,它将存储一些私有的更多信息,因此希望它从 CWinThread 派生。

请提出建议。

【问题讨论】:

【参考方案1】:

是的,您可以在不使用 AfxBeginThread 的情况下创建工作线程。

您可以覆盖虚拟 int Run();函数将您的代码放在那里并在函数末尾调用 ExitInstance() 以结束线程。要启动你的线程,你可以调用 AfxBeginThread,或者简单地调用你的线程对象上的 CreateThead 函数

//First option
CMyThread* pMyThread = (CMyThread*)AfxBeginThread(RUNTIME_CLASS(CMyThread));

//Second option
CMyThread myThread;
myThread.CreateThread();

也许这不是 MFC 的官方方式,但它确实有效!

【讨论】:

AfxBeginThread 文档说 CRuntimeClass 应该是从 CWinThread 派生的对象的 RUNTIME_CLASS。这似乎是所要求的。 是的,这是我的示例中的第一个选项。【参考方案2】:

文档表明创建“真正的”MFC 工作线程的唯一方法是通过AfxBeginThread()。但是,您可以通过创建派生的 CWinThread 对象、调用它、完成InitInstance() 中的所有工作,然后终止线程来近似工作线程。

【讨论】:

【参考方案3】:

您不需要从 CWinThread 派生来存储一些对工作线程私有的更多信息。 AfxBeginThread 的 AFX_THREADPROC 函数指针版本采用可用于传递任何内容的 LPVOID 参数。一个简单的字符串,一个充满私人信息的结构,甚至是a pointer to the class that called AfxBeginThread(注意同步,不要从工作线程中触摸GUI。)

// static
UINT TaskingDialog::Worker(LPVOID p)

    TaskingDialog* self = (TaskingDialog*)p;
    //grab data from self, do work, etc, quick thread
    return 0;


void TaskingDialog::OnStartThread()

    // start a simple worker thread that finishes quickly
    AfxBeginThread(Worker, this);

【讨论】:

OP 要求将 CWinThread 派生类作为工作线程。 @Goldorak84 是的,但他们给出想要使用它的原因是为了存储重要的私人信息。我认为最好遵循文档而不是从 CWinThread 派生工作线程。 documentation 关于工作线程是这样说的:“创建工作线程是一项相对简单的任务。让你的线程运行只需要两个步骤:实现控制功能和启动线程。不必从 CWinThread 派生类。如果需要特殊版本的 CWinThread,可以派生类,但大多数简单的工作线程不需要它。您可以不加修改地使用 CWinThread。"

以上是关于如何使用 CWinThread 在 MFC 中创建工作线程?的主要内容,如果未能解决你的问题,请参考以下文章

MFC 和 AfxBeginThread 的线程调度问题

CWinThread 查询 (MFC)

如何在 MFC 中创建圆角矩形按钮

如何在 C++/MFC/GDI 中创建一个非常大的位图

未调用 MFC 的 CWinThread::PostThreadMessage 处理程序

debug和release下PostThreadMessage的异同