0

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によって渡されます。afterChecktreeView

MSDNのこの例によると、すべてが正常に機能するはずですが、代わりにコンパイラエラーが発生します。

エラーC3350:'System :: Threading :: ThreadStart':デリゲートコンストラクターは2つの引数を必要とします

エラーC2102:'&'にはl値が必要です

MSDNの例に示されているとおりの新しいインスタンスを作成しようとしましたForm1が、結果は同じです。


@Tudorがadivcedしたものがトリックを行いました。しかし、System :: Threadingを使用すると、Form1クラスのコンポーネントを変更できませんでした。だから私は他の解決策を探していました、そして私はこれを見つけまし

そして多分私は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));
         }
4

1 に答える 1

3

関数呼び出しにパラメーターを指定する必要はありません。

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

また、関数はパラメーターをとらないでください。そうしないと、ThreadStart署名に準拠しません。

その他の例については、MSDN ページを参照してください。Thread

于 2012-07-10T17:52:33.910 に答える