0
在以下代碼中(用/ clr編譯)故意寫入控制檯,線程要麼凍結GUI,要麼不提供任何結果。Visual Studio WinForm C++線程不安全
歡迎任何想法。 還特別是這一行this-> Invoke(d,gcnew array {AA,BB}); 只有2個參數,代碼編譯。如果我根據委託需要嘗試3個參數,則代碼不會編譯。任何想法爲什麼?
請幫助。
#include <iostream>
#include <stdlib.h>
#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Threading;
using namespace System::Windows::Forms;
#define NN 1000000
unsigned long long AA = 0;
unsigned long long BB = 99999999999999999ull;
unsigned long long PP[NN];
bool IsPrime(unsigned long long number)
{
if (number == 2 || number == 3)
return true;
if (number % 2 == 0 || number % 3 == 0)
return false;
int divisor = 6;
while (divisor * divisor - 2 * divisor + 1 <= number)
{
if (number % (divisor - 1) == 0)
return false;
if (number % (divisor + 1) == 0)
return false;
divisor += 6;
}
return true;
}
void NextPrime(unsigned long long a, unsigned long long * prime)
{
while (!IsPrime(++a))
{
}
* prime = a;
}
void FindAllPrimes(unsigned long long a, unsigned long long b, unsigned long long * prime)
{
unsigned long long k, n;
n = 0;
for (k = a; k < b; k++)
{
if (IsPrime(k))
{
prime[n] = k;
n++;
if (n >= 1000000)
{
break;
}
}
}
}
namespace MyNameSpace
{
public ref class Form1 : public Form
{
delegate void Delegate_Call(unsigned long long a, unsigned long long b, unsigned long long * prime);
private: void Function_1()
{
FindAllPrimes(AA, BB, PP);
}
private: void Function_2()
{
this->Function_3(AA, BB, PP);
}
private: void Function_3(unsigned long long a, unsigned long long b, unsigned long long * prime)
{
if (this->textBox1->InvokeRequired)
{
Delegate_Call^ d = gcnew Delegate_Call(this, &Form1::Function_3);
this->Invoke(d, gcnew array<Object^> { AA, BB });
int n = rand() % NN;
this->textBox1->Text = PP[n].ToString();
for (int n = 0; n < NN; n++)
std::cout << PP[n] << std::endl;
}
else
{
FindAllPrimes(AA, BB, PP);
int n = rand() % NN;
this->textBox1->Text = PP[n].ToString();
for (int n = 0; n < NN; n++)
std::cout << PP[n] << std::endl;
}
}
private: Thread^ Thread_A;
private: BackgroundWorker^ backgroundWorker1;
private: TextBox^ textBox1;
private: Button^ Button_DoNotKnow;
private: Button^ Button_UnSafeCall;
private: Button^ Button_SafeCall;
private: Button^ Button_BGWorker;
private: System::ComponentModel::IContainer^ components;
public: Form1()
{
components = nullptr;
InitializeComponent();
}
protected: ~Form1()
{
if (components != nullptr)
{
delete components;
}
}
private: void InitializeComponent()
{
this->textBox1 = gcnew System::Windows::Forms::TextBox();
this->Button_DoNotKnow = gcnew System::Windows::Forms::Button();
this->Button_UnSafeCall = gcnew System::Windows::Forms::Button();
this->Button_SafeCall = gcnew System::Windows::Forms::Button();
this->Button_BGWorker = gcnew System::Windows::Forms::Button();
this->backgroundWorker1 = gcnew System::ComponentModel::BackgroundWorker();
this->SuspendLayout();
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(30, 30);
this->textBox1->Name = "textBox1";
this->textBox1->Size = System::Drawing::Size(310, 20);
this->textBox1->TabIndex = 0;
//
// Button_DoNotKnow
//
this->Button_DoNotKnow->Location = System::Drawing::Point(20, 70);
this->Button_DoNotKnow->Name = "Button_DoNotKnow";
this->Button_DoNotKnow->TabIndex = 1;
this->Button_DoNotKnow->Text = "DoNotKnow";
this->Button_DoNotKnow->Click += gcnew System::EventHandler(this, &Form1::Button_DoNotKnow_Click);
//
// Button_UnSafeCall
//
this->Button_UnSafeCall->Location = System::Drawing::Point(100, 70);
this->Button_UnSafeCall->Name = "Button_UnSafeCall";
this->Button_UnSafeCall->TabIndex = 2;
this->Button_UnSafeCall->Text = "Unsafe Call";
this->Button_UnSafeCall->Click += gcnew System::EventHandler(this, &Form1::Button_UnSafeCall_Click);
//
// Button_SafeCall
//
this->Button_SafeCall->Location = System::Drawing::Point(180, 70);
this->Button_SafeCall->Name = "Button_SafeCall";
this->Button_SafeCall->TabIndex = 3;
this->Button_SafeCall->Text = "Safe Call";
this->Button_SafeCall->Click += gcnew System::EventHandler(this, &Form1::Button_SafeCall_Click);
//
// Button_BGWorker
//
this->Button_BGWorker->Location = System::Drawing::Point(260, 70);
this->Button_BGWorker->Name = "Button_BGWorker";
this->Button_BGWorker->TabIndex = 4;
this->Button_BGWorker->Text = "Safe BW Call";
this->Button_BGWorker->Click += gcnew System::EventHandler(this, &Form1::Button_BGWorker_Click);
//
// backgroundWorker1
//
this->backgroundWorker1->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &Form1::backgroundWorker1_RunWorkerCompleted);
//
// Form1
//
this->ClientSize = System::Drawing::Size(380, 180);
this->Controls->Add(this->Button_BGWorker);
this->Controls->Add(this->Button_SafeCall);
this->Controls->Add(this->Button_UnSafeCall);
this->Controls->Add(this->Button_DoNotKnow);
this->Controls->Add(this->textBox1);
this->Name = "Form1";
this->Text = "Form1";
this->ResumeLayout(false);
this->PerformLayout();
}
private: void Button_DoNotKnow_Click(Object^ sender, EventArgs^ e)
{
FindAllPrimes(AA, BB, PP);
for (int n = 0; n < NN; n++)
std::cout << PP[n] << std::endl;
}
private: void Button_UnSafeCall_Click(Object^ sender, EventArgs^ e)
{
this->Thread_A = gcnew Thread(gcnew ThreadStart(this, &Form1::Function_1));
this->Thread_A->Start();
}
private: void Button_SafeCall_Click(Object^ sender, EventArgs^ e)
{
this->Thread_A = gcnew Thread(gcnew ThreadStart(this, &Form1::Function_2));
this->Thread_A->Start();
}
private: void Button_BGWorker_Click(Object^ sender, EventArgs^ e)
{
this->backgroundWorker1->RunWorkerAsync();
}
private: void backgroundWorker1_RunWorkerCompleted(Object^ sender, RunWorkerCompletedEventArgs^ e)
{
FindAllPrimes(AA, BB, PP);
for (int n = 0; n < NN; n++)
std::cout << PP[n] << std::endl;
}
};
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew MyNameSpace::Form1());
}
非常感謝您的回答。我想繼續打印100萬行。這是爲了項目中的其他要求。我嘗試了您的更改,代碼正在控制檯上打印,但我無法移動GUI。或按任意按鈕(稍後我想添加一個按鈕以取消)您是否可以在打印到控制檯時幫助使GUI響應。你也可以寫一些代碼如何啓動一個無GUI線程,以及如何將函數調用移動到非GUI線程。先謝謝你。 – Hatems