65.9K
CodeProject 正在变化。 阅读更多。
Home

CThread

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.60/5 (6投票s)

2005年7月30日

Ms-RL

3分钟阅读

viewsIcon

68977

downloadIcon

1622

CThread 简化了启动、运行和停止线程的过程。您可以像在 C# 或 Java 中那样使用它来处理线程。

引言

CThread 使在 MFC 中使用线程几乎可以与在 C#/Java 中使用线程的方式相同。您可以从 CThread 派生自己的类并实现 Run(void* )。要启动线程,您必须调用 Start()。现在,新线程将在 Run() 中开始其执行。当 Run() 完成时,线程将停止其执行。

使用代码

要使用该代码,您应该从 CThread 派生您的类。您还必须实现 Run 函数,线程将在其中执行。例如

class CMyThread : public CThread
{
    void Run(void* param);
}

如果您想从多个类派生,这是可以的,如果您想在对话框类中运行线程,这种情况很常见。

class CMyThread : public CDialog, CThread
{
    void Run(void* param);
}

启动线程

启动线程非常简单,只需调用 Start()。现在,新线程将在 Run() 中开始其执行。如果线程已在运行,则不应调用 Start()。要检查这一点,请调用 IsRunning()

您可以向线程发送一个可选的指针参数。如果您这样做,请确保该指针有效。以下示例将不起作用

{
    int parameter = 10;
    Start(&paramater);
}

当您调用 Start() 时,指针是有效的,但在线程开始执行时,它可能不总是有效的。请改用 new

{
    int* parameter = new int(10);
    Start(&paramater);
}

不要忘记在 Run() 中删除对象。参数以 void 指针的形式发送到 Run() 中的线程。您也可以使用成员变量将信息发送到线程。

停止线程

要停止线程,请调用 Stop()。这将 **不会** 立即停止线程;而是设置一个标志,告诉线程停止其执行。如果您想等待线程退出,请调用 WaitForStop()

运行线程

线程需要做什么取决于您。线程将在您必须实现的 Run() 函数中开始执行。当线程退出 Run() 时,它将完成其执行。在实现 Run() 时,您必须检查线程是否应停止执行。如果某个线程调用了 Stop(),则为真。要检查该标志,请调用 ShouldRun()。例如

void CMyThread::Run(void* param)
{
    //Run the thread until someone has called Stop()
    while( ShouldRun() )
    {
        ...
    }
}

从线程发送消息

很多时候您想从线程更新 GUI。例如,您想更新一个进度条。最直接的解决方案是从线程直接更新进度条。例如

void CMyThreadInDialog::Run(void* param)
{
    ...
    m_progressbar.SetPos(10)
    ...
}

但这 **不会** 起作用。Windows 的一个黄金法则是,只有一个线程应该操作 GUI。为此,您应该使用消息。从在 Run() 中执行的线程,您应该向主线程发送一条消息,告诉窗口进行更新。您 **不** 应该使用 SendMessage,而应该使用 PostMessageSendMessage 直接从线程更新 GUI,这并非您想要的。PostMessage 将消息添加到窗口的消息队列中,并将由主线程处理。

所以您的代码应该看起来像这样

void CMyThreadInDialog::Run(void* param)
{
    ...
    ::PostMessage(UPDATE_PROGRESSBAR, m_hWnd, 10, 0);
    ...
}

有关更多详细信息,请参阅示例。

关注点

在我编写这个类之前,我在 CodeProject 上寻找过类似的东西。令我惊讶的是,我没有找到关于这个主题的文章。但我没有足够努力地寻找……至少有两篇文章提供了类似的解决方案

  • CThread

    一个比我的 CThread 更复杂的解决方案(顺便说一句,我很抱歉名字冲突)。但值得一看。

  • AG_Thread

    这是一个比我的 CThread 更简单的解决方案。

即使我不是第一个撰写有关此主题的文章的人,我也希望有人会发现这个类很有用 :-)

历史

  • 2005年7月30日 - 版本 1.0。初始版本。
  • 2005年8月21日 - 版本 1.01。Blake Miller 建议的次要修复和改进。
© . All rights reserved.