Kon*_*rad 8 c# asp.net-core-mvc asp.net-core asp.net-core-webapi
这是一个很好的做法,无论操作是否很长,总是在我的操作中添加CancellationToken?
我现在正在将它添加到每个动作中,我不知道它是对还是错.
[Route("api/[controller]")]
public class DummiesController : Controller
{
private readonly AppDbContext _dbContext;
public DummyController(AppDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpGet("{id}")]
public async Task<ActionResult<Dummy>> GetAsync(int id, CancellationToken ct) // <<----- should I always do this?
{
var dummy = await _dbContext.Dummies.AsNoTracking().SingleOrDefaultAsync(e=>e.Id == id, ct);
if (dummy == null) return NotFound();
return dummy;
}
}
Run Code Online (Sandbox Code Playgroud)
还有CancellationToken ct = default(CancellationToken)必要吗?
Teo*_*ahi 24
我应该总是将 CancellationToken 添加到我的控制器操作中吗?
不。你不应该总是。
在 ASP.NET Core MVC 控制器中使用 CancellationTokens
https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/
这是否是正确的行为将取决于您的应用程序。如果 请求修改了状态,那么您可能不想在方法中途停止执行。另一方面,如果请求没有副作用,那么您可能希望尽快停止(可能是昂贵的)操作。
因此,如果您有如下所示的方法/操作(简化);
await ProcessOrder();
await UpdateInventory();
Run Code Online (Sandbox Code Playgroud)
您不希望在处理订单时取消订单,如果是这样,订单可以完成,但如果用户通过隧道并失去互联网连接,您将不会更新库存。
当操作不能包含在像模式(例如分布式系统)这样的工作单元中并且应该尽量减少取消时,这一点尤其重要。
小智 13
我认为取消令牌应该主要用于查询类型操作。以CRUD(创建、读取、更新、删除)操作为例,基于CQRS(命令查询职责分离)进行分解。
可以看到,对于Query操作来说,随时取消都不会有问题。但对于 Command,您很可能不想取消任何操作。例如Create,假设你正在为2个独立的数据库创建数据,然后中途被取消,就会导致数据不同步。
如果您对外部资源有任何依赖性,则值得添加。
假设您的数据库很忙,或者您已经为数据库连接准备了临时错误处理/重试策略。如果最终用户在其浏览器中按下Stop键,则取消令牌将帮助(在您的代码中)所有等待操作正常地取消。
不用考虑正常情况下的长期运行特性,而考虑不理想情况下的长期运行特性,例如,如果在Azure中运行并且您的SQL数据库正在进行例行维护,并且实体框架配置为重试自身(假设实体框架响应取消)令牌)。
附带说明:Polly弹性框架为外部取消令牌提供了出色的支持,以协调来自外部取消的重试取消。他们的Wiki值得一读,因为它是协调取消的大开眼界:https : //github.com/App-vNext/Polly/wiki
关于CancellationToken ct = default(CancellationToken),在库代码上可能比在Controller操作上更有价值。但是,如果您要直接对控制器进行单元测试但又不想传递取消令牌,则非常方便。话虽这么说,如今比起直接测试控制器动作,.net core的WebHostBuilder测试框架更易于测试。
| 归档时间: |
|
| 查看次数: |
3206 次 |
| 最近记录: |