2017-08-16 77 views
2

如何使用std::thread为UWP应用程序创建线程?对不起,我在创建对象内的成员函数的线程所需的语法方面存在问题。我刚开始在visual studio中使用C++/cx。这里是我的代码:如何在UWP中的对象的成员函数内使用std :: thread 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); 
} 

编辑:

我有这些错误:

ERROR1:

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

误差2:

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

您的线程对象在创建后立即超出范围。你应该加入它,即'th.join();'。 – Azeem

+0

@Azeem尽管我添加了'th.join()'它仍然不能解决问题。感谢您的建议 – Gibs

+2

很久以前,我放弃了'bind'-style语法,只是使用lambda:'std :: thread th([this] {this-> increment(5);});'。 –

回答

2

我不确切地知道你的公司有什么问题nstructor调用 - 绑定风格的语法是非常古怪的,并给出了最糟糕的可能的错误信息。

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

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

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

话虽这么说,你的代码是错误的逻辑在多个层次上。

正如已经在注释中声明的那样,由于您的线程立即超出了范围,因此std::thread不希望在线程结束之前销毁,或者您显式地将创建的线程从线程分离目的。所以:

  • 要么你打电话join,在这种情况下,根本没有任何意义,因为现在你的主线程将被停止以等待工作线程,这样启动线程处于首位无用的;
  • 或你detach它,这是不好的,因为现在你可以有失控的线程;如果你关闭了应用程序窗口,你仍然可以运行线程,对正在销毁的数据进行操作。

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

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

有一些方法可以实现安全的跨线程GUI调用(通常归结为通过GUI事件队列传递消息) - this article可能有一些与UWP相关的建议 - 但它就像使用大炮射击蚊子;在你的情况下,你所需要的仅仅是一个普通的定时器,不需要任何线程。

相关问题