c++ - 如何在 UWP C++/CX 中的对象的成员函数内使用 std::thread

标签 c++ multithreading c++-cx

如何使用 std::thread 为 UWP 应用程序创建线程?抱歉,我对在对象内创建成员函数线程所需的语法有疑问。我刚刚开始在 Visual Studio 中使用 c++/cx。这是我的代码:

void MainPage::increment(int val)
{
    for (int i = 0; i < val; ++i){
        m_timer4++;
        Sleep(100);
        textBox4->Text = m_timer4.ToString();
    }
}

void _4ThreadsUWP::MainPage::button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    m_timer->Start();
    std::thread th(&MainPage::increment, this, 5);
}

编辑:

我遇到了这些错误:

错误1:

'std::invoke': no matching overloaded function found

错误2:

Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'

最佳答案

我不知道你的构造函数调用到底出了什么问题——绑定(bind)样式的语法是出了名的古怪,并且给出了最糟糕的错误消息。

我的建议是完全避免 std::bind 及其邪恶的兄弟(例如这个 std::thread 构造函数),并尽可能使用 lambda 函数。它们有自己的怪癖,但它们通常更容易理解,错误消息并不完全是垃圾,而且它们有更多的应用程序。

在这种情况下,你可以这样做:

std::thread th([this]{this->increment(5);});

话虽如此,您的代码在多个层面上都是逻辑错误的。

正如评论中已经指出的那样,由于您的线程立即超出范围,因此您将收到异常,因为 std::thread 不想在线程结束或之前被销毁您显式地将创建的线程与线程对象分离。所以:

  • 要么调用join,在这种情况下这是没有意义的,因为现在你的主线程将停止等待工作线程,因此启动线程首先是没有用的;<
  • 或者你分离它,这很糟糕,因为现在你可能有失控的线程;如果关闭应用程序窗口,线程可能仍在运行,对正在被销毁的数据进行操作。

更好的解决方案是在类级别移动工作线程,在单击按钮时启动它(如果尚未启动)并在窗口关闭时加入它。

但是:无论如何,所有这些都是无用的,因为在几乎每个 GUI 工具包(包括 UWP)中,GUI 对象都不是线程安全的。从非主 UI 线程的线程调用它们的方法会导致不稳定的行为和崩溃,而您的代码正是这样做的。

有多种方法可以进行安全的跨线程 GUI 调用(通常归结为通过 GUI 事件队列传递消息)- this article可能有一些与UWP相关的建议——但这就像用大炮射击蚊子;在您的情况下,您所需要的只是一个常规计时器,没有任何线程。

关于c++ - 如何在 UWP C++/CX 中的对象的成员函数内使用 std::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45707490/

相关文章:

c++ - C:将指针数组作为参数传递给结构体

c++ - 无法在 cmake 中包含外部先前构建的 .a 库

C++:如何将十六进制字符转换为无符号字符?

c - 如何在线程中共享内存

c++ - 创建任务并返回值

c++ - 我可以从同一个文件夹为 mingw 和 windows 构建 boost 吗?

java - java中使用线程的定时器

c# - 线程意外退出时抛出什么异常?

sockets - 在 Metro 中处理套接字创建/销毁时的泄漏

c++ - UWP : WACK test failing on Windows Runtime metadata validation