2012-03-12 61 views
1

私はC#で開発されたWindowsサービスを持っています。今すぐメソッドBackgroundFoldersProcessingは、次のようになりますタスクをキャンセルするか、タスクの実行を即座に終了するには?

Task _backgroundTask = null; 

CancellationTokenSource _backgroundCancellationSource = null; 

protected override void OnStart(string[] args) 
{ 

...... 

_backgroundCancellationSource = new CancellationTokenSource(); 

CancellationToken token = backgroundCancellationSource.Token; 

_backgroundTask = new Task(() => BackgroundFoldersProcessing(token), token, TaskCreationOptions.LongRunning); 

....... 
} 

:それはStartメソッドのオンのような私は、初期化を持って

void BackgroundFoldersProcessing(CancellationToken token) 
{ 

      while (true) 
      { 
       try 
       { 
        if (token.IsCancellationRequested) 
        {       
         return; 
        } 

        DoSomeWork() 
       } 
       catch (Exception ex) 
       { 
        ......... 
       } 
      } 
} 

を今、以下のように、Stopメソッドは次のとおりです。今

protected override void OnStop() 
{ 
................. 

_backgroundCancellationSource.Cancel(); 
_backgroundTask.Wait(); 

_backgroundCancellationSource.Dispose(); 
_backgroundTask.Dispose(); 

_backgroundTask = null; 
_backgroundCancellationSource = null; 

................. 
} 

問題は、処理の途中でサービスを停止しようとしたときに、_backgroundTaskのWaitメソッドがサービスを停止しない限り、DoSomeWork()メソッドがBackgroundFold ersProcessingが完了すると、Windowsサービスは停止しません。

DoSomeWork()メソッドが完了/実行されても、サービスを停止して_backgroundTaskの実行を終了する方法はありますか?私もbackgroundFoldersProcessingメソッドでtoken.ThrowIfCancellationRequested()を試してみましたが、それもうまくいきませんでした。 Service Control Manager(SCM)からサービスを停止しようとするたびに、サービスをすぐに停止し、__backgroundTaskでBackgroundFoldersProcessingメソッドの実行を停止し、終了させる必要があります。どうすればこれを達成できますか?

+0

DoSomeWork()は時間がかかりすぎますか?あなたはそれが完了するのを待っています。 Wait(TimeSpan)のオーバーロードを試行し、3秒に設定するとよいでしょう。 –

+0

@NikolaMarkovinovićはい、DoSomeWork()は入力に応じてかなり長い時間がかかります。実際、私はPackage(.zip)ファイルを入力として与えています。したがって、パッケージの処理には、パッケージの内容に応じて数秒から数分かかることがあります。そして、実際に私はWait(TimeSpan)とWait(int milliSeconds)と他のオーバーロードされたWaitメソッドを試しました。そして、はい、それは働いた。ありがとう。 –

答えて

0

あなたは利用ThreadAbortExceptionの試すことができます:あなたが使用し、それをシャットダウンしたいときBackgroundFoldersProcessing

catch (ThreadAbortException e) 
{ 
    return; 
} 

にキャッチを追加し、

ThreadStart threadDelegate = new ThreadStart(BackgroundFoldersProcessing); 
Thread thread_ = new Thread(threadDelegate); 
thread_.Start(); 

thread_.Abort(); 
thread_.Join(); 

がスレッドを定義します

Then Abort()が呼び出され、ThreadAbortExceptionがスローされます。

+0

これは良いアプローチかもしれませんし、シングルスレッド環境ではうまくいくかもしれませんが、私はマルチスレッド環境でのスレッドセーフについて懸念しています。コードをクラスに移動してWorkと言うとします。 WorkクラスではStart()メソッドとStop()メソッドを開発し、そのメソッドをWindowsサービスのOnStartとOnStopで呼び出すことができます。では、Workクラスの複数のインスタンスを作成して使用すると、あなたが提案するアプローチはスレッドセーフで、実行されるスレッドはすべて非同期で実行されますか? –

関連する問題