取消操作的重要性体现在提升用户体验、优化资源管理、避免状态不一致和构建响应式服务;2. 在复杂异步流程中,应通过将cancellationtoken作为参数逐层传递、使用createlinkedtokensource组合多个取消条件、并在并行操作中通过paralleloptions或task.whenall确保每个任务都能响应取消,从而实现有效的取消传递与处理,最终保证系统能够及时、优雅地响应取消请求并释放资源。

OperationCanceledException
处理取消请求,核心在于使用
CancellationTokenSource
CancellationToken
你需要一个
CancellationTokenSource
CancellationTokenSource cts = new CancellationTokenSource(); // 在某个时机,比如用户点击了“取消”按钮 // cts.Cancel();
然后,将
cts.Token
CancellationToken
在你的操作内部,你需要定期检查这个令牌的状态。最直接的方式是调用
cancellationToken.ThrowIfCancellationRequested()
OperationCanceledException
public async Task DoSomethingCancellableAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 100; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // 检查并抛出异常
Console.WriteLine($"Processing item {i}");
await Task.Delay(100); // 模拟耗时操作
}
}在调用这个可取消操作的地方,你需要用
try-catch
OperationCanceledException
try
{
await DoSomethingCancellableAsync(cts.Token);
Console.WriteLine("Operation completed successfully.");
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was cancelled.");
// 这里可以进行一些清理工作,比如释放资源
}
finally
{
cts.Dispose(); // 记得释放 CancellationTokenSource
}除了
ThrowIfCancellationRequested()
cancellationToken.IsCancellationRequested
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Cancellation requested, performing graceful shutdown...");
// 执行一些清理或保存状态的操作
cancellationToken.ThrowIfCancellationRequested(); // 或者最后还是抛出,保持一致性
}最后,别忘了
CancellationTokenSource
IDisposable
Dispose
取消操作在构建响应式、健壮的现代应用程序中,其重要性真的不言而喻。我个人觉得,它不仅仅是一个“功能”,更是一种设计哲学。你想想看,一个用户启动了一个耗时的数据导入,突然发现选错了文件,他会怎么做?他肯定想立刻停止。如果没有取消机制,程序可能就傻傻地继续执行,直到完成或者出错,这用户体验简直是灾难。
它主要体现在几个方面:
我见过不少项目,在设计初期忽略了取消机制,结果后期为了解决用户抱怨或者服务器过载问题,不得不进行大规模的重构,那真是吃力不讨好。所以,从一开始就考虑任务的可取消性,绝对是明智之举。
在简单的例子里,直接传递
CancellationToken
一个核心原则是:将 CancellationToken
CancellationToken
// 顶层方法
public async Task OrchestrateProcessAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await Step1Async(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
await Step2Async(cancellationToken);
// ...
}
// 中间层方法
public async Task Step1Async(CancellationToken cancellationToken)
{
// 可以在这里创建新的 CancellationTokenSource,用于组合取消
// CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, someOtherToken);
// await SubStepAsync(linkedCts.Token);
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(500, cancellationToken); // Task.Delay 也支持 CancellationToken
Console.WriteLine("Step 1 done.");
}组合取消令牌 (Linked Tokens): 有时候,你可能需要一个操作在多个取消信号中的任意一个被触发时就停止。例如,既要响应外部的取消请求,又要响应内部的超时。这时,
CancellationTokenSource.CreateLinkedTokenSource
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // 5秒后自动取消
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(externalCancellationToken, timeoutCts.Token);
try
{
await DoLongRunningOperationAsync(linkedCts.Token);
}
catch (OperationCanceledException ex) when (ex.CancellationToken == timeoutCts.Token)
{
Console.WriteLine("Operation timed out!");
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation cancelled by external request.");
}这里有个小细节,
when (ex.CancellationToken == timeoutCts.Token)
CancellationToken
在并行和并发操作中的处理: 当你使用
Task.WhenAll
Parallel.ForEach
Parallel.ForEach
ParallelOptions
CancellationToken
Task.WhenAll
Task
// Parallel.ForEach 示例
var options = new ParallelOptions { CancellationToken = cancellationToken };
try
{
Parallel.ForEach(items, options, item =>
{
options.CancellationToken.ThrowIfCancellationRequested();
// 处理 item
});
}
catch (OperationCanceledException)
{
Console.WriteLine("Parallel operation cancelled.");
}
// Task.WhenAll 示例
var tasks = new List<Task>();
foreach (var item in items)
{
tasks.Add(ProcessItemAsync(item, cancellationToken)); // 确保 ProcessItemAsync 内部处理取消
}
try
{
await Task.WhenAll(tasks);
}
catch (OperationCanceledException)
{
Console.WriteLine("One or more tasks were cancelled.");
}我发现很多人在处理复杂异步流程时,容易忘记
以上就是C#的OperationCanceledException是什么?如何处理取消请求?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号