如何使用 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/