WP8.1 - CancellationToken和async仍在等待永远,永远不会结束

时间:2014-11-07 01:46:24

标签: c# xaml windows-store-apps windows-phone-8.1 win-universal-app

我有一个非常奇怪的问题,我不知道如何解决它。 我在不同的类中有这两种方法。 按下CommandBar中的按钮时会触发第一个。

编辑:我创建了两个相似但更小的方法来向您展示问题:

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

我添加了一个在1500ms后过期的cancellationToken(我假设如果解释器需要更长的时间来处理代码,它就会陷入循环中。)

我第一次尝试这个通常是有效的,但如果我再试一次,CommandBar按钮永远不会再次启用,所以我认为这个任务正在等待永远,我不知道为什么,因为我添加了cancelToken

你知道这里有什么问题吗? 谢谢你的帮助!

塞尔吉奥

1 个答案:

答案 0 :(得分: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,然后是任务和程序退出。

相关问题