Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading [C+;+;,windows窗体]如何使主线程等待调用的线程完成?_Multithreading_C++ Cli - Fatal编程技术网

Multithreading [C+;+;,windows窗体]如何使主线程等待调用的线程完成?

Multithreading [C+;+;,windows窗体]如何使主线程等待调用的线程完成?,multithreading,c++-cli,Multithreading,C++ Cli,我创建了两个按钮,一个用于启动新线程,另一个用于结束它。新线程中的实际计算涉及new[]和delete[],因此我不直接中止线程,而是使用一个标志来结束它。结束delete[]和结果保存可能需要一些时间,因此我希望主线程等待新线程结束。但是不管我怎么尝试,我发现新线程在停止按钮的命令行执行之前不会运行(尽管它的ThreadState正在运行)。系统::线程::线程的工作原理与我的线程大不相同。应该是这样吗 #include "stdafx.h" ref class Form1 : System

我创建了两个按钮,一个用于启动新线程,另一个用于结束它。新线程中的实际计算涉及new[]和delete[],因此我不直接中止线程,而是使用一个标志来结束它。结束delete[]和结果保存可能需要一些时间,因此我希望主线程等待新线程结束。但是不管我怎么尝试,我发现新线程在停止按钮的命令行执行之前不会运行(尽管它的ThreadState正在运行)。系统::线程::线程的工作原理与我的线程大不相同。应该是这样吗

#include "stdafx.h"

ref class Form1 : System::Windows::Forms::Form
{
public:
//define a thread name and a flag to terminate the thread
System::Threading::Thread^ th1;
static bool ITP1=0;

Form1(void)
{InitializeComponent();}

System::Windows::Forms::Button^ ButtonStart;
System::Windows::Forms::Button^ ButtonStop;
System::Windows::Forms::Label^ Label1;

void InitializeComponent(void)
{
    this->SuspendLayout();

    this->ButtonStart = gcnew System::Windows::Forms::Button();
    this->ButtonStart->Location = System::Drawing::Point(20, 20);
    this->ButtonStart->Click += gcnew System::EventHandler(this, &Form1::ButtonStart_Click);
    this->Controls->Add(this->ButtonStart);

    this->ButtonStop = gcnew System::Windows::Forms::Button();
    this->ButtonStop->Location = System::Drawing::Point(120, 20);
    this->ButtonStop->Click += gcnew System::EventHandler(this, &Form1::ButtonStop_Click);
    this->Controls->Add(this->ButtonStop);

    this->Label1 = gcnew System::Windows::Forms::Label();
    this->Label1->Location = System::Drawing::Point(20, 80);
    this->Controls->Add(this->Label1);

    this->ResumeLayout(false);
    }

void ThreadStart()
{
    for (int idx=0;idx<999999999;++idx)
    {
        if (ITP1) break;
    }
    this->Label1->Text = "finished";
    ITP1=0;
}

System::Void ButtonStart_Click(System::Object^ sender, System::EventArgs^ e)
{
    th1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1::ThreadStart));
    th1->Start();
    this->Label1->Text = "running";
}

System::Void ButtonStop_Click(System::Object^ sender, System::EventArgs^ e)
{
    if (th1->ThreadState==System::Threading::ThreadState::Running)
    {
        //use the flag to stop the thread
        ITP1=1;
        //the wait method using while+sleep doesn't work
        while (th1->ThreadState==System::Threading::ThreadState::Running)   System::Threading::Thread::Sleep(1000);
        //replacing the wait method above with "th1->Join()" doesn't work either
    }
}
};

int main()
{
Form1^ A1 = gcnew Form1();
A1->ShowDialog();
return 0;
}
#包括“stdafx.h”
ref类Form1:System::Windows::Forms::Form
{
公众:
//定义线程名称和终止线程的标志
系统::线程::线程^th1;
静态布尔ITP1=0;
表格1(无效)
{InitializeComponent();}
系统::Windows::窗体::按钮^ButtonStart;
系统::Windows::窗体::按钮^ButtonStop;
系统::Windows::窗体::标签^Label1;
void初始化组件(void)
{
此->SuspendLayout();
此->按钮开始=gcnew System::Windows::Forms::Button();
此->按钮开始->位置=系统::图纸::点(20,20);
此->按钮启动->单击+=gcnew System::EventHandler(此,&Form1::按钮启动\u单击);
此->控制->添加(此->按钮开始);
此->按钮Stop=gcnew System::Windows::Forms::Button();
此->按钮停止->位置=系统::图纸::点(120,20);
this->ButtonStop->Click+=gcnewsystem::EventHandler(this,&Form1::ButtonStop\u Click);
此->控制->添加(此->按钮停止);
这->Label1=gcnew System::Windows::Forms::Label();
此->标签1->位置=系统::图纸::点(20,80);
此->控制->添加(此->标签1);
此->恢复布局(错误);
}
void ThreadStart()
{
对于(int idx=0;idxLabel1->Text=“finished”;
ITP1=0;
}
系统::无效按钮开始单击(系统::对象^sender,系统::事件参数^e)
{
th1=gcnew-System::Threading::Thread(gcnew-System::Threading::ThreadStart(this,&Form1::ThreadStart));
th1->Start();
此->标签1->文本=“正在运行”;
}
System::Void按钮停止单击(System::Object^sender,System::EventArgs^e)
{
if(th1->ThreadState==System::Threading::ThreadState::Running)
{
//使用该标志停止线程
ITP1=1;
//使用while+sleep的等待方法不起作用
而(th1->ThreadState==System::Threading::ThreadState::Running)System::Threading::Thread::Sleep(1000);
//用“th1->Join()”替换上面的等待方法也不起作用
}
}
};
int main()
{
Form1^A1=gcnewform1();
A1->ShowDialog();
返回0;
}
您必须在主线程中加入被调用线程。然后主线程将等待被调用线程完成


请参阅文档以了解如何调用它。

最后我找到了原因。它只是新线程中的“this->”指针。删除它会使一切正常。
我想这是因为表单只允许同时对一个元素进行操作。我让按钮单击以等待新线程,新线程尝试编辑另一个表单元素。它们等待彼此结束并导致死循环。

您如何确定它不运行?是否使用调试器查看发生了什么?是的。我在System::Void Button Stop_Click下添加一个中断。th1->ThreadState始终在运行,尽管没有执行任何操作。因此while循环已停止。您是否在线程内放置了断点?这是知道它是否正在运行的唯一方法,因为它不执行任何操作。对于我的VC++express,调试无法正确使用线程。命令行按钮下面是它能走多远。但我将ThreadState打印到标签上。因此,在没有调试的情况下,我也知道它是在运行还是停止。“
Join
me,我们一起统治世界。”-Darth Threader在我问这个问题之前,我已经阅读了此文档。事实上,我在主线程中使用了Join()(表单由主函数调用),而文档似乎在新线程中使用它。我的所有脚本都在上面。您可以看到我只创建了一个线程,并使用ButtonStop_Click停止它。因此ButtonStop_Click只能从主线程调用。看起来您正在使用
th1->Join()
在创建的线程中。应该在启动创建的线程后不久在主线程中调用联接。No.th1->join()在主线程的表单类中调用。谢谢大家。我必须找到其他解决方案。我需要创建的线程将结果返回到UI并更新进度栏,这样我就不能简单地删除“this”指针。