Как создать и запустить новый поток?
Я создал System::Windows::Forms
класс, который определяет функцию:
System::Void expanding(System::Windows::Forms::TreeViewEventArgs^ e)
{
//some code
}
Который я хочу вызвать в отдельном потоке, набрав:
Thread^ thisThread = gcnew Thread(
gcnew ThreadStart(this,&Form1::expanding(e)));
thisThread->Start();
где e
проходит мимо afterCheck
функция от treeView
составная часть.
Согласно этому примеру из MSDN все должно работать нормально, но вместо этого я получаю ошибку компилятора:
ошибка C3350: 'System::Threading::ThreadStart': конструктор делегата ожидает 2 аргумента
а также
ошибка C2102: '&' требует l-значение
Я пытался создать новый экземпляр Form1
точно так, как это было показано в примере MSDN, но мои результаты такие же.
То, что @Tudor Adivced сделал свое дело. Но, используя System:: Threading, я не смог изменить ни один компонент из класса Form1. Так что я искал какое-то другое решение, и я нашел это
И, возможно, я не понимаю, как работает BackgroundWorker, но он блокирует графический интерфейс.
То, что я хотел сделать, - это запустить отдельный поток (каким бы способом это ни было нужно сделать), который оставит GUI управляемым, так что пользователь сможет остановить процесс с определенной кнопкой, и этот новый поток сможет использовать компоненты из родительского потока,
вот мой пример кода с использованием BackgroundWorker
//Worker initialization
this->backgroundWorker1->WorkerReportsProgress = true;
this->backgroundWorker1->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &Form1::backgroundWorker1_DoWork);
this->backgroundWorker1->ProgressChanged += gcnew System::ComponentModel::ProgressChangedEventHandler(this, &Form1::backgroundWorker1_ProgressChanged);
this->backgroundWorker1->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &Form1::backgroundWorker1_RunWorkerCompleted);
Асинхронная операция вызывается обработчиком события нажатия кнопки.
System::Void fetchClick(System::Object^ sender, System::EventArgs^ e) {
dirsCreator();//List of directories to be fetched
backgroundWorker1 ->RunWorkerAsync();
}
ФункцияDoWork - это базовая функция рекурсивного извлечения
System::Void fetch(String^ thisFile)
{
try{
DirectoryInfo^ dirs = gcnew DirectoryInfo(thisFile);
array<FileSystemInfo^>^dir = (dirs->GetFileSystemInfos());
if(dir->Length>0)
for(int i =0 ;i<dir->Length;i++)
{
if((dir[i]->Attributes & FileAttributes::Directory) == FileAttributes::Directory)
fetch(dir[i]->FullName);
else
**backgroundWorker1 -> ReportProgress(0, dir[i]->FullName);**//here i send results to be printed on gui RichTextBox
}
}catch(...){}
}
А вот функция отчетности
System::Void backgroundWorker1_ProgressChanged(System::Object^ sender, System::ComponentModel::ProgressChangedEventArgs^ e) {
this->outputBox->AppendText((e->UserState->ToString())+"\n");
this->progressBar1->Value = (this->rand->Next(1, 99));
}
1 ответ
Вам не нужно указывать параметр для вызова функции:
Thread^ thisThread = gcnew Thread(
gcnew ThreadStart(this,&Form1::expanding));
thisThread->Start();
Также функция не должна принимать никаких параметров, в противном случае она не соответствует ThreadStart
подпись.
Взгляните на страницу MSDN Thread
еще несколько примеров.