不使用async/await如何返回抛出OperationCanceledException的已取消ValueTask<T>
解决方案
面向.NET 6+ 版本的最优方案
.NET 6 开始ValueTask<T>官方新增了FromCanceled<T>(CancellationToken)静态方法,直接完美匹配你的需求,实现代码如下:
ValueTask<int> MyMethod(CancellationToken token) { if (token.IsCancellationRequested) return ValueTask.FromCanceled<int>(token); // 剩余业务逻辑 return ValueTask.FromResult(13); }
该实现和async写法的行为100%一致:
- 返回的
ValueTask<int>的IsCanceled属性为true - 等待时抛出
OperationCanceledException,符合预期要求
兼容.NET 5及更早版本的替代方案
如果需要适配低版本.NET框架,可以通过一个极简的async辅助方法生成符合要求的已取消ValueTask,性能开销可以忽略不计:
static ValueTask<T> GetCanceledValueTask<T>(CancellationToken token) { async ValueTask<T> Generate() { token.ThrowIfCancellationRequested(); return default; } return Generate(); } // 业务方法调用 ValueTask<int> MyMethod(CancellationToken token) { if (token.IsCancellationRequested) return GetCanceledValueTask<int>(token); // 剩余业务逻辑 return ValueTask.FromResult(13); }
补充说明
TaskCanceledException本身是OperationCanceledException的子类,常规业务代码中捕获OperationCanceledException即可覆盖两种取消场景,不会影响逻辑运行。你提到的Channel类的异常不一致问题属于.NET早期版本的历史遗留问题,在.NET 6及以上版本的官方实现中已经修复。
内容的提问来源于stack exchange,提问作者Theodor Zoulias
相关产品推荐
相关产品推荐

