C# CancellationTokens:链式调用是否应该传递相同的调用?
C# CancellationTokens: Should Chained Calls Pass the Same One Down?
我目前正在使用 Mediator,其 Handle()
方法接受 CancellationToken
作为参数。我有一个场景,我将几个处理请求链接在一起。
public async Task<Foo> Handle(CreateFoo createFoo, CancellationToken cancellationToken)
{
// Re-use CancellationToken, or use a new one?
Bar newBar = await _mediator.Send(createFoo.CreateBar, cancellationToken);
// Rest of Handle code snipped.
}
之前我没有将令牌传递到此处的 Send()
方法调用,但后来我认为令牌应该向下传递,因为它是同一请求的一部分。这是正确的,还是我不应该像上面那样重新使用取消令牌?
我认为这个问题的答案不仅适用于 Mediator,而且适用于 C# 中使用 CancellationToken
.
的所有内容
取消令牌是一个轻量级结构。它按值复制。它应该被传递到不同级别的功能。
所以你想传多少取消令牌都可以。
但请确保您的取消始终与单个操作相关联。如果操作被取消,则它被取消。您无法恢复取消并重新使用令牌。
只要您在设计时牢记这一点,看来您传递取消令牌的方式是正确的。
您的另一个选择是创建一个单独的取消标记。为此,您需要创建一个新的 CancellationTokenSource。这是一次性物品。因此,您必须在使用结束后小心处理它。而且相比CancellationToken,它的重量也不轻。因此,如果您不合乎逻辑地开始可以取消的新操作,我不建议使用新的 CancellationTokenSource。
有关详细信息,请查看 documentation
从文档中提取的重要部分,
1)
The object that invokes one or more cancelable operations, for example
by creating new threads or tasks, passes the token to each operation.
Individual operations can in turn pass copies of the token to other
operations. At some later time, the object that created the token can
use it to request that the operations stop what they are doing.
2)
In the new cancellation framework, cancellation refers to operations,
not objects. The cancellation request means that the operation should
stop as soon as possible after any required cleanup is performed. One
cancellation token should refer to one "cancelable operation," however
that operation may be implemented in your program. After the
IsCancellationRequested property of the token has been set to true, it
cannot be reset to false. Therefore, cancellation tokens cannot be
reused after they have been canceled.
3)
The CancellationTokenSource class implements the IDisposable
interface. You should be sure to call the
CancellationTokenSource.Dispose method when you have finished using
the cancellation token source to free any unmanaged resources it holds
我目前正在使用 Mediator,其 Handle()
方法接受 CancellationToken
作为参数。我有一个场景,我将几个处理请求链接在一起。
public async Task<Foo> Handle(CreateFoo createFoo, CancellationToken cancellationToken)
{
// Re-use CancellationToken, or use a new one?
Bar newBar = await _mediator.Send(createFoo.CreateBar, cancellationToken);
// Rest of Handle code snipped.
}
之前我没有将令牌传递到此处的 Send()
方法调用,但后来我认为令牌应该向下传递,因为它是同一请求的一部分。这是正确的,还是我不应该像上面那样重新使用取消令牌?
我认为这个问题的答案不仅适用于 Mediator,而且适用于 C# 中使用 CancellationToken
.
取消令牌是一个轻量级结构。它按值复制。它应该被传递到不同级别的功能。
所以你想传多少取消令牌都可以。
但请确保您的取消始终与单个操作相关联。如果操作被取消,则它被取消。您无法恢复取消并重新使用令牌。
只要您在设计时牢记这一点,看来您传递取消令牌的方式是正确的。
您的另一个选择是创建一个单独的取消标记。为此,您需要创建一个新的 CancellationTokenSource。这是一次性物品。因此,您必须在使用结束后小心处理它。而且相比CancellationToken,它的重量也不轻。因此,如果您不合乎逻辑地开始可以取消的新操作,我不建议使用新的 CancellationTokenSource。
有关详细信息,请查看 documentation
从文档中提取的重要部分,
1)
The object that invokes one or more cancelable operations, for example by creating new threads or tasks, passes the token to each operation. Individual operations can in turn pass copies of the token to other operations. At some later time, the object that created the token can use it to request that the operations stop what they are doing.
2)
In the new cancellation framework, cancellation refers to operations, not objects. The cancellation request means that the operation should stop as soon as possible after any required cleanup is performed. One cancellation token should refer to one "cancelable operation," however that operation may be implemented in your program. After the IsCancellationRequested property of the token has been set to true, it cannot be reset to false. Therefore, cancellation tokens cannot be reused after they have been canceled.
3)
The CancellationTokenSource class implements the IDisposable interface. You should be sure to call the CancellationTokenSource.Dispose method when you have finished using the cancellation token source to free any unmanaged resources it holds