【问题标题】:How to create and run a new thread?如何创建和运行一个新线程?
【发布时间】:2012-07-10 17:49:56
【问题描述】:

我创建了一个定义函数的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();

其中eafterCheck 函数从treeView 组件传递。

根据this example from MSDN,一切都应该可以正常工作,但我得到一个编译器错误:

错误 C3350:“System::Threading::ThreadStart”:委托构造函数需要 2 个参数

错误 C2102:“&”需要左值

我尝试完全按照 MSDN 示例中所示创建 Form1 的新实例,但结果相同。


@Tudor adivced 做到了这一点。但是使用 System::Threading 我无法修改 Form1 类中的任何组件。 所以我一直在寻找其他解决方案,我找到了this

也许我不明白 BackgroundWorker 的工作方式,但它会阻止 GUI。

我想要完成的是运行单独的线程(无论它需要以何种方式完成),这将使 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));
         }

【问题讨论】:

  • 请注意,Visual C++ 只是 IDE。 C++/CLI 是 Microsoft 添加以支持托管集成的 C++ 扩展的名称。

标签: .net winforms multithreading c++-cli managed-c++


【解决方案1】:

您不必为函数调用指定参数:

Thread^ thisThread = gcnew Thread(
         gcnew ThreadStart(this,&Form1::expanding));
         thisThread->Start();

另外函数不应该带任何参数,否则不符合ThreadStart签名。

请查看ThreadMSDN page 以获得更多示例。

【讨论】:

  • +1,在 OP 的示例中,他试图获取方法调用的返回值的地址。
  • Form1::expanding 在 C++/CLI 中对于实例方法是正确的。委托构造函数的第一个参数this 指定要在哪个对象上调用该方法。
  • @David Yaw:对,对不起,不知道我在想什么。 :)
猜你喜欢
  • 1970-01-01
  • 2019-08-16
  • 2020-01-01
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2010-11-27
  • 1970-01-01
相关资源
最近更新 更多