2014-03-07 64 views
0

我試圖運行一個異步任務,取消它,並再次運行它,但是當我第一次取消它時,我不能再運行它了,我做錯了嗎?無法重新運行一個取消的任務

Private TypeTask As Threading.Tasks.Task 
Private TypeTaskCTS As New Threading.CancellationTokenSource 
Private TypeTaskCT As Threading.CancellationToken = TypeTaskCTS.Token 
Private RequestCancel As Boolean = True 

Private Sub TypeWritter(ByVal CancellationToken As Threading.CancellationToken, 
         ByVal [Text] As String, 
         ByVal TypeSpeed As Integer, 
         ByVal PauseSpeed As Integer) 

    ' For each Character in text to type... 
    For Each c As Char In [Text] 

     ' If not want to cancel then... 
     If Not CancellationToken.IsCancellationRequested Then 

      ' Type the character. 
      Console.Write(CStr(c)) 

      ' Type-Wait. 
      Threading.Thread.Sleep(TypeSpeed) 

      If ".,;:".Contains(c) Then 
       ' Pause-Wait. 
       Threading.Thread.Sleep(PauseSpeed) 
      End If 

     Else ' want to cancel. 

      ' Reset the request cancellation. 
      RequestCancel = False 

      ' Exit iteration. 
      Exit For 

     End If ' CancellationToken.IsCancellationRequested 

    Next c ' As Char In [Text] 

End Sub 

Public Sub TypeWritter(ByVal [Text] As String, 
         Optional ByVal TypeSpeed As Integer = 75, 
         Optional ByVal PauseSpeed As Integer = 400) 

    ' Run the asynchronous Task. 
    TypeTask = Threading.Tasks. 
       Task.Factory.StartNew(Sub() 
             TypeWritter(TypeTaskCT, [Text], TypeSpeed, PauseSpeed) 
            End Sub, TypeTaskCT) 

    ' Until Task is not completed or is not cancelled, do... 
    Do Until TypeTask.IsCompleted OrElse TypeTask.IsCanceled 

     If RequestCancel Then 

      If Not TypeTaskCTS.IsCancellationRequested Then 
       TypeTaskCTS.Cancel 
      End If 

      RequestCancel = False 
      Exit Do 

     End If 

    Loop ' TypeTask.IsCompleted OrElse TypeTask.IsCanceled 

End Sub 

Public Sub TypeWritterLine(ByVal [Text] As String, 
          Optional ByVal TypeSpeed As Integer = 75, 
          Optional ByVal PauseSpeed As Integer = 400) 

    TypeWritter([Text] & vbCrLf, TypeSpeed, PauseSpeed) 
    Console.WriteLine() 

End Sub 

通知變量:

Private RequestCancel As Boolean = True 

用於第一次(只是爲了使事情更快的測試會發生什麼,當我嘗試調用任務時被設置爲True取消任務第二次,我期待錯誤)。

,我試圖用法是這樣的:

Sub Main() 

    RequestCancel = True ' This should cancel this task: 
    TypeWritterLine("Some text") 

    ' And this task should run as normally, but it doesn't, I get an empty line: 
    TypeWritterLine("Some other text") 

End Sub 

回答

1

這是由設計。任務總是執行一次,即使之前未開始取消。這意味着您必須注意不要多次調用任務的Start方法。 對於「重新運行」任務,您將不得不再次調用Task.Factory.StartNew方法。

+0

'爲了「重新運行」一個任務,你將不得不再次調用Task.Factory.StartNew方法'是的,但我認爲這已經是我在我的代碼中每次調用該方法的時候...'TypeTask = Threading.Tasks.Factory.StartNew(Sub()...' – ElektroStudios

+1

我創建了一個簡單的例子,它可以多次啓動一些任務,執行完成後,我試着運行你的代碼,這樣做後,我注意到你總是工作使用相同的cancellationToken實例當第一次取消一個任務時,這個令牌會記住已經有一個取消請求,並且進一步的任務不會被執行,確保你使用了一個CancellationTokenSource和CancellationToken的新實例,然後它會工作 –

+0

謝謝你這麼多。 – ElektroStudios