2014-10-02 36 views
2

我正在研究一個應用程序,其中有一個可以停止的任務&稍後重新啓動。 的,我已經兩個方法:如何在C中重新啓動System.Threading.Tasks.Task#

public static void TaskProcess() 
    { 
     var tokenSource = new CancellationTokenSource(); 
     CancellationToken token = tokenSource.Token; 
     var task = new Task(
      () => 
       { 
        DoWork(token); 
       }, 
      token); 

     task.ContinueWith(
      task1 => 
       { 
        Console.WriteLine("Task finished... press any key to continue"); 
        Console.ReadKey(); 
        Console.WriteLine("Press q to quit..."); 
       }, 
      token); 

     task.Start(); 

     string input; 
     while ((input = Console.ReadLine()) != "q") 
     { 
      if (input == "c") 
      { 
       tokenSource.Cancel(); 
      } 
      if (input == "r") 
      { 
       if (task.IsCompleted) 
       { 
        // Here i want to restart my completed task 
       } 
       else 
       { 
        Console.WriteLine("Task is not completed"); 
       } 
      } 
     } 
    } 

    private static void DoWork(CancellationToken token) 
    { 
     int i = 0; 
     while (true) 
     { 
      i++; 
      Console.WriteLine("{0} Task continue...", i); 
      Thread.Sleep(1000); 

      if (token.IsCancellationRequested) 
      { 
       Console.WriteLine("Canceling"); 
       token.ThrowIfCancellationRequested(); 
      } 
     } 
    } 

目前,我創建任務和的CancellationToken的新實例,以「重啓」的任務,但我正在尋找更好的東西如果可能的話:

if (input == "r") 
      { 
       if (task.IsCompleted) 
       { 
        Console.WriteLine("Task is completed... Restarting"); 
        tokenSource = new CancellationTokenSource(); 
        token = tokenSource.Token; 
        CancellationToken token1 = token; 
        task = new Task(
         () => DoWork(token1), 
         token); 
        task.Start(); 
       } 
       else 
       { 
        Console.WriteLine("Task is not completed"); 
       } 
      } 

謝謝你的幫助。

回答

3

不,TaskTaskCancellationSource是使用和拋出的對象。你不能重用它們。您必須像現在一樣創建新對象。

它是有道理的,假設你已經取消了Task,稍後某些代碼需要檢查Task的狀態。它在你重新啓動任務後不久就會出現(不可能,請說明),請問這不是誤導性,告知狀態是Running已經爲Canceled任務?

+0

如果我每次重新啓動時都重新創建新實例,這對內存來說還不夠嗎? – Younes 2014-10-02 13:33:20

+0

@cYounes是什麼讓你這樣想? – 2014-10-02 13:36:19

+0

,因爲這段代碼將在一個服務中永久運行,並且要確保它不會產生任何錯誤:) – Younes 2014-10-02 13:41:24

2

如果你想重新開始System.Threading.Tasks.Task<TResult>,我不認爲你可以:作爲Task Cancellation guide說,當取消調用任務必須終止,而且由於任務已經結束,你不能重新啓動它;所以你在做什麼是正確的。

或者你問是否有更好的模式來處理這種工作流程?

+0

Exaclty,我在做什麼能正常工作,但是我擔心內存,如果我每次重新啓動過程時都創建新的實例 – Younes 2014-10-02 13:36:14

+1

爲什麼你擔心使用過的內存?任務在啓動時從缺省線程池(具有固定數量的可用線程)分配,並在終止時釋放,因此除非您泄漏對象或掛起任務,否則不會有內存問題。你可以*擁有開始新任務的開銷,但只有你可以評估。 – Albireo 2014-10-02 13:40:05