我有这段代码,我想得到一些有关 CancellationToken 的使用的说明。
我读到了这个关于使用取消 token 和标志之间的区别的问题:
Difference between CancellationTokenSource and exit flag for Task loop exit
我注意到的一件事是它没有提到任何有关异常的内容。这是我的问题。 如果调用 Disappearing() 方法,那么这是否会导致 TaskCanceledException() 发生,这是否是使用 CancellationToken 而不是标志的好理由?
public partial class PhrasesFrame : Frame
{
CancellationTokenSource cts = new CancellationTokenSource();
public PhrasesFrame(PhrasesPage phrasesPage)
{
Device.BeginInvokeOnMainThread(() => ShowCards(cts.Token).ContinueWith((arg) => { }));
}
public void Disappearing()
{
cts.Cancel();
}
public async Task ShowCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await PickCard();
}
}
public async Task PickCard()
{
await ShowCard();
}
private async Task ShowCard()
{
await ShowPhrase();
await ShowDetail();
}
private async Task ShowPhrase()
{
while (App.pauseCard || timer1Seconds > 0)
{
try
{
await Task.Delay(1000, tokenSource1.Token);
}
catch (TaskCanceledException)
{
// do action
break;
}
}
最佳答案
CancellationTokenSource.Cancel
本身不会引发此类异常,但它将所有相关取消 token “移动”到已取消状态。当某些代码通知取消 token 现在处于取消状态时 - 它可能抛出此类异常。如果看你的例子,这部分不会抛出这样的异常:
public async Task ShowCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await PickCard();
}
}
因为你只是不把它扔到这个 block 中。然而,如果你做了这样的事情:
public async Task ShowCards(CancellationToken ct)
{
while (true)
{
ct.ThrowIfCancellationRequested();
await PickCard();
}
}
然后就会抛出异常,因为,你几乎明确地抛出了它。
现在,如果看一下示例中的另一种方法:
private async Task ShowPhrase()
{
while (App.pauseCard || timer1Seconds > 0)
{
try
{
await Task.Delay(1000, tokenSource1.Token);
}
catch (TaskCanceledException)
{
// do action
break;
}
}
}
如果您正在等待 Task.Delay(1000, tokenSource1.Token);
,然后取消 tokenSource1
- 那么 TaskCancelledException
确实会被抛出立即执行,无需等待 Task.Delay
的整个持续时间。这是仅使用 bool 标志无法轻松实现的目标。如果您使用了 Thread.Sleep(1000) 和 bool 标志 - 在整个 sleep 期间完成之前,不会注意到对该标志的更改。
因此,回答您的问题:在您的示例中,可能会或可能不会引发异常,具体取决于您取消 CancellationTokenSource
时当前正在执行的代码部分(我假设使用两个取消名为 cts
和 tokenSource1
的 token 源只是代码中的拼写错误,但如果它是真实代码 - 那么根本不能抛出此类异常,因为您取消了 cts
但 Task.Delay
等待 tokenSource1
)。
关于c# - 取消 CancellationToken 是否会导致 CancellationToken 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47967118/