2017-02-10 20 views
1

スレッドの実行が完了した後に関数を実行しようとしています。 UIボタンが押されてスレッドが完了するまでに時間がかかると、スレッドが開始されます。
実行が終了したら、関数を呼び出したいと思います。ここで私がこれまでに試したコードです。私のコードを実行しようとすると、スレッドは決して実行されず、アプリケーションはフリーズします。これを修正する方法に関する提案は役に立ちます。スレッドの実行終了後の関数の実行

public bool StartProbe() 
{ 
    if (File.Exists(Path.Combine(ObsProbeFolder, "probePJM.exe"))) 
    { 
     ThreadStart ProbeThreadStart = new ThreadStart(() => 
     // right side of lambda  
      { 
       // does stuff 
      }); 

      ProbeThread = new Thread(ProbeThreadStart); 
      ProbeThread.Priority = ThreadPriority.BelowNormal; 
      ProbeThread.SetApartmentState(ApartmentState.STA); 
      ProbeThread.Start(); 

    } 
    else 
    {      
     return false; 
    } 

    // waiting for thread to finish 
    ProbeThread.Join(); 
    // run a function 
    loadData(); 

    return true; 
} 
+1

forループであなたの 'ProbeThread.Join();'をラップしたのはなぜですか? – Madenis

+0

私は最初にforループなしでそれを飽きさせましたが、それでも私には同じ問題がありました。だから私はそれが修正されるかどうかを見るためにforループで疲れましたが、それはしませんでした。 – Satish

+0

UIスレッドは 'someThread.Join();'を実行するとフリーズします。これは、UIスレッドが他のスレッドが停止するまでブロックするためです。 – Maarten

答えて

0

私は、BackgroundWorkerの使用します。BackgroundWorkerを使用しないでください

private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // load data or whatever on UI thread 
    } 
+0

TPLを使用したり待機したりすることができる場合は、なぜBackgroundWorkerなどの古い構造を使用しますか? – VMAtm

+0

BackgroundWorkerの使用には何も問題はありません。特に、説明されているユーザーなどの単一のプロセスでは問題ありません。私は、TPLは複数のプロセスを実行する方が優れていることに同意しますが、単一プロセスでは事実上互換性があります。 – mjhouseman

0

- :代替スレッドで

Worker = new BackgroundWorker(); 
      Worker.RunWorkerCompleted += Worker_RunWorkerCompleted; 
      Worker.DoWork += Worker_DoWork; 

      Worker.RunWorkerAsync(new BackgroundArguments() 
      { 
       // arguments 
      }); 

が仕事:UIスレッドへ

private void Worker_DoWork(object sender, DoWorkEventArgs e) 
{  
    // do stuff 
} 

が戻りますそれはかなりの古いクラスですが、私はMSによっていつかは廃止されると言います。

あなたは、ボタンを持っていると言いますが、fire-and-forgetシナリオ用のasync voidイベントハンドラを作成します。 exeファイルを確認しているので、私はあなたがProcess in backgroundを実行していると仮定します。また、プロセスを実行するためのスレッドは必要ありません。参加するとUIがハングアップするのです。

private async void button_Click(object sender, EventArgs e) 
{ 
    // wait for a result from outer process 
    var result = await RunProcessInBackGround(); 
    //do whatever you need in the UI-context 
    loadData(result); 
} 

// T is a type of the result, should be changed 
private async Task<T> RunProcessInBackGround() 
{ 
    var tcs = new TaskCompletionSource<T>(); 
    // run your process 
    var process new Process {/* your params here */}; 
    process.Exited += (sender, args) => 
     { 
      // here your process has already done his job 
      tcs.SetResult(result); 
      process.Dispose(); 
     }; 
    // process will start as a separate process, no need to create a thread to wait for it 
    process.Start(); 
    // return the task which will be awaited for 
    return tcs.Task; 
} 
関連する問題