我有一个非常奇怪的问题,我不知道如何解决它。 我在不同的类中有这两种方法。 按下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
你知道这里有什么问题吗? 谢谢你的帮助!
塞尔吉奥
答案 0 :(得分:5)
你大概是2/3的路。使用CancellationToken
+ CancellationTokenSournce
时,必须询问令牌是否已取消。有多种方式可以订阅,包括调用令牌的ThrowIfCancelledRequest方法或检查令牌的Boolean
属性IsCancellationRequested和break
走出循环。请参阅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
,然后是任务和程序退出。