3

我有一個非常奇怪的問題,我不知道如何解決它。 我有這兩種方法在不同的類。 當CommandBar中的按鈕被按下時,第一個被觸發。WP8.1 - CancellationToken和異步仍然等待永遠,永不結束

編輯:我創建了兩個類似但更小的方法向您展示問題:

private async void runCode(object sender, RoutedEventArgs e) 
    { 
     BottomAppBar.IsEnabled = false; 
     object result = await endlessLoopTest(); 
     BottomAppBar.IsEnabled = true; 
    } 

    private async Task<object> endlessLoopTest() 
    { 
     var tokenSource = new System.Threading.CancellationTokenSource(500); 
     try 
     { 
      await Task.Run(() => 
      { 
       while (true) 
       { 
        //Infinite loop to test the code 
       } 
      }, tokenSource.Token); 
      return null; 
     } 
     catch (OperationCanceledException) 
     { 
      return new TextBlock(); 
     } 
    } 

我加了的CancellationToken是1500毫秒後到期(我假設,如果翻譯需要更長的時間來處理的代碼,它有被困在一個循環中)。

我第一次嘗試這種方法通常可行,但如果我再試一次,CommandBar按鈕永遠不會再次啓用,所以我認爲該任務將永久等待,並且我不知道爲什麼,因爲我添加了的CancellationToken。

你知道這裏可能是錯的嗎? 感謝您的幫助!

塞爾吉奧

+0

請提供更好的代碼示例。一個簡潔,但實際上可以由其他人編譯和運行。如果你也可以放棄罵人的話,那會很好。見http://stackoverflow.com/help/mcve – 2014-11-07 02:05:16

+0

哈哈,這是我正在解釋的語言的實際名稱ahahahah我忘了切出來,對不起:) 我編輯我的帖子用兩個小方法重現問題,再次感謝您的幫助! – Sergio0694 2014-11-07 02:30:33

回答

5

你是那裏的2/3。當使用CancellationToken + CancellationTokenSournce時,必須詢問令牌是否被取消。有許多方法可以訂閱,包括調用令牌的ThrowIfCancelledRequest方法或檢查令牌的Boolean屬性IsCancellationRequestedbreak。見Cancellation in Managed Threads

這是一個可以在控制檯應用程序中運行的小例子。請注意,在基於UI的應用程序中,請使用await,而不是Task.Wait()

private static void CancelTask() 
    { 
     CancellationTokenSource cts = new CancellationTokenSource(750); 
     Task.Run(() => 
     { 
      int count = 0; 
      while (true) 
      { 
       Thread.Sleep(250); 
       Console.WriteLine(count++); 
       if (cts.Token.IsCancellationRequested) 
       { 
        break; 
       } 
      } 
     }, cts.Token).Wait(); 
    } 

結果是0 1 2然後任務和程序退出。

+1

謝謝,是作品!可能進入無限循環的方法是一個遞歸的方法,它內部也有一個goto,我在跳轉標籤後面添加了一個ThrowIfCancelledRequest(),並且它可以工作:D 我只是不明白它是如何可能的當使用斷點調試應用程序時,它在我添加Throw方法之前工作。 我的意思是,任務無論如何都被取消了。 反正,非常感謝你的幫助! :) – Sergio0694 2014-11-07 10:08:13