2012-12-31 16 views
5

私はBackgroundWorkerで実行中のプロセスを持つアプリケーションを作成しています。私はユーザーインターフェイスからのキャンセルをサポートしたいと思いますが、これを簡単に行う方法はありません。System.Diagnostics.Process.Start()経由でプロセスをキャンセルする

Processは、実際にはかなり長い実行コマンドラインのexeです。出力はProgress.OutputDataReceivedイベントを介して非同期的にリダイレクトされ、GUIに進行状況を報告するために使用されています。

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    using (var process = new Process()) 
    { 
     //... 

     process.Start() 

     //... 

     process.WaitForExit(); 
    } 
} 

private void CancelWorker() 
{ 
    worker.CancelAsync(); 
    // where to actually listen for the cancellation??? 
} 

StandardInput別にメインスレッドからの入力のために、「聞く」プロセスを持つ方法があるようには表示されませんが、それは動作しませんしない限り、アプリ自体の意志特定に応じ入力を中止します。

メインスレッドからのキャンセル要求に基づいてプロセスをキャンセルする方法はありますか?私のプロセスで実行中のEXEのの目的のために

、私はただの副作用せずに終了しProcess.Close()を呼び出すことができますが、Processオブジェクトだけworker_DoWork()方法にはよく知られているので、私はトラックを保持する必要がありますProcessインスタンスの中止の目的のために...それは私がよりよい方法があるかもしれないことを望んでいる理由です。

(それが重要ならば、私は互換性の問題のための.NET 3.5をターゲットにしています。)

+1

あなたはBGワーカープロセスを開始している理由はありますか?これは一般的に長い時間がかからない呼び出しです(起動するプログラムには時間がかかるかもしれませんが、それはそれ自身のプロセスになります)。 – keyboardP

+0

これは実際にはバックグラウンドワーカーではありませんが、カスタムAsyncメソッドでは、 'BackgroundWorker'は状況を説明するのが簡単です。しかし、これはバックグラウンドスレッドで実行されている大きなプロセスの一部です。 – psubsee2003

+0

あなたのDoWorkメソッド内に多少の負荷がかかっていない限り、スレッドが数ミリ秒以内にジョブを終了したため、CancelAsyncは機能しません。 'using'は良い習慣ですが、コード内の他の場所から' Process'にアクセスできる必要があるので、 'Process'を保持するクラスレベルの変数を持ち、' ​​Process.Close'を呼び出すことができます。あなたのスレッドが返ってくるか、プロセスがもはや必要でなくなったときに、プロセスに対して 'Dispose'を呼び出すことを覚えておいてください。 – keyboardP

答えて

3

、これはあなたを助けるかもしれない、これを試してみてください、あなたがする必要がありますBackgroundWorker.CancellationPending BackgroundWorker.DoWork イベントで聞きます。

How to: Use a Background Worker

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    using (var process = new Process()) 
    { 
     //... 

     process.Start() 

     //... 
     while(true) 
     { 
      if ((sender as BackgroundWorker).CancellationPending && !process.HasExited) 
      { 
       process.Kill(); 
       break; 
      } 
      Thread.Sleep(100); 
     } 

     process.WaitForExit(); 
    } 
} 
+0

良い提案ですが、 'while(true)'のために、キャンセルが受信されない限りループは終了しません。私は 'while(!process.HasExited)'に変更し、完璧に動作します。ありがとうございます。 – psubsee2003

-1

協力キャンセルのための簡単な方法で

private System.Threading.TimerCallback worker; 
private System.Threading.Timer workertimer ; 
private void worker_DoWork() 
{ 
    //You codes 
} 
private void StartWorker() 
{ 
    worker = new System.Threading.TimerCallback(worker_DoWork); 
    workertimer = new System.Threading.Timer(worker, null, 1000, 1000); 
} 

private void CancelWorker() 
{ 
    worker.Dispose(); 
} 
+2

'Dispose'メソッドで' process'がどのように殺されたかはわかりません。どのように機能するのですか? – Tilak

関連する問題