2012-03-12 128 views
1

我有一個在C#中開發的Windows服務。在它的Start方法,我有一個初始化如:如何取消任務或立即終止任務執行?

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); 

....... 
} 

現在的方法BackgroundFoldersProcessing看起來是這樣的:

void BackgroundFoldersProcessing(CancellationToken token) 
{ 

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

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

現在,停止方法如下:

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

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

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

_backgroundTask = null; 
_backgroundCancellationSource = null; 

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

現在問題是當我嘗試在處理中途停止服務時,_backgroundTask的Wait方法不會停止服務,直到並且除非BackgroundFold中的DoSomeWork()方法ersProcessing完成後,Windows服務不會停止。

有沒有什麼辦法,雖然我可以停止服務,並且_backgroundTask的執行將被終止,即使DoSomeWork()方法得到完成/執行或沒有?我也嘗試過BackgroundFoldersProcessing方法中的token.ThrowIfCancellationRequested(),但那也沒有奏效。我希望每當我嘗試停止服務控制管理器(SCM)的服務時,服務應該立即停止,__backgroundTask應該停止執行BackgroundFoldersProcessing方法並終止。我怎樣才能做到這一點?

+0

DoSomeWork()只是花了太長時間?你正在等待它完成。您可能想嘗試Wait(TimeSpan)超載並將其設置爲三秒。 – 2012-03-12 09:00:09

+0

@NikolaMarkovinović是的,DoSomeWork()需要相當長的時間取決於輸入。實際上,我將Package(.zip)文件作爲輸入。因此,處理一個軟件包可能需要幾秒到幾分鐘時間,具體取決於軟件包的內容。而且,實際上我嘗試了Wait(TimeSpan)以及Wait(int milliSeconds)和其他重載的Wait方法。是的,它的工作。謝謝。 – 2012-03-12 09:57:03

回答

0

您可以嘗試使用ThreadAbortException:

限定螺紋:

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

添加捕捉到BackgroundFoldersProcessing

catch (ThreadAbortException e) 
{ 
    return; 
} 

,當你想關閉它使用:

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

然後當中止()將被稱爲ThreadAbortException將被拋出。

+0

這可能是一個很好的方法,它可能在單線程環境中運行良好,但我擔心多線程環境中的線程安全問題。假設我將代碼移動到一個類中,然後說Work。在Work類中,我可以開發一個方法Start()和Stop(),並在Windows Service的OnStart和OnStop中調用該方法。現在,如果我創建並使用Work類的多個實例,那麼您建議的方法是否是線程安全的,並且所有運行的線程是否會異步執行? – 2012-03-12 10:17:39