Ung*_*ant 3 c# service background-service cancellationtokensource cancellation-token
我对此很陌生。周围的信息很多,我有点困惑。我想确认我的理解是否正确并感谢任何帮助。我将在 (i) 中对每个问题进行编号,以便更容易回答。
我有一个带有 ExecuteAsync(CancellationToken CancellationToken) 和 StopAsync(CancellationToken CancellationToken) 的BackgroundService。
我假设这两种方法在服务运行时都会获得相同的令牌。(1) 这是真的吗?
如果我理解正确,只要取消标记未标记为取消,我就应该使用 ExecuteAsync 中的取消标记来执行某些操作。ExecuteAsync 有一个 while 循环,在取消令牌未取消时运行迭代。每次迭代都会等待某些事情发生,并可能启动一些异步任务。
当我启动这些任务时,我应该从链接到cancellationToken的新CancellationTokenSource给它们一个CancellationToken,以便(A)任务知道何时应该取消服务以及何时应该取消任务本身(但是,在后一种情况,无需取消服务本身);(B) 使cancellationToken用完。(2) (A)和(B)正确吗?
简单地在某些 CancellationTokenSource 上调用 Cancel() 实际上并不会自动取消我的任务或引发异常。这个逻辑由我来定义。(3)这是真的吗?
这让我想到了另一个问题。假设我发现内部某个任务确实被标记为取消。什么是正确/预期的行为?我应该清理任务的资源,然后对我拥有的令牌使用 ThrowIfCancellationRequested() 吗?(4)这是真的吗?
最后,当服务本身被取消时,即当 ExecuteAsync 的主循环发现其令牌被取消时,我应该如何表现。(5) 我应该立即 ThrowIfCancellationRequested 吗?我应该先清理资源,然后再 ThrowIfCancellationRequested 吗?或者我应该只调用 ThrowIfCancellationRequested 作为 StopAsync 的最后一行?
我有一个带有 ExecuteAsync(CancellationToken CancellationToken) 和 StopAsync(CancellationToken CancellationToken) 的BackgroundService。
不。您在这里混合了不同级别的抽象。
BackgroundService要么与 一起使用ExecuteAsync ,要么IHostedService与StartAsyncand一起使用StopAsync。
你可能只需要ExecuteAsync. 这对大多数人来说都很好。
我假设这两种方法在服务运行时都会获得相同的令牌。(1) 这是真的吗?
StartAsync不会。传递给、StopAsync和的取消标记ExecuteAsync都是不同的。
如果我理解正确,只要取消标记未标记为取消,我就应该使用 ExecuteAsync 中的取消标记来执行某些操作。
是的。ExecuteAsync当后台服务需要停止时,传递给的取消令牌将被取消。
当我启动这些任务时,我应该从链接到cancellationToken的新CancellationTokenSource给它们一个CancellationToken
您是否只需要取消一个任务?如果是这样,那么是的。如果没有的话,直接传过去就可以了cancellationToken。
简单地在某些 CancellationTokenSource 上调用 Cancel() 实际上并不会自动取消我的任务或引发异常。这个逻辑由我来定义。(3)这是真的吗?
是的。必须遵守取消标记。这通常是通过以下方式完成的:
ThrowIfCancellationRequested.这让我想到了另一个问题。假设我发现内部某个任务确实被标记为取消。什么是正确/预期的行为?我应该清理任务的资源,然后对我拥有的令牌使用 ThrowIfCancellationRequested() 吗?(4)这是真的吗?
更好:始终在报表中定义您的资源using。然后您就可以ThrowIfCancellationRequested在需要时进行操作。
同样,99% 的情况下,正确处理取消只需将令牌传递给其他已经支持取消的方法即可。
最后,当服务本身被取消时,即当 ExecuteAsync 的主循环发现其令牌被取消时,我应该如何表现。(5) 我应该立即 ThrowIfCancellationRequested 吗?我应该先清理资源,然后再 ThrowIfCancellationRequested 吗?
以同样的方式处理它:如果您的方法是可取消的,只需将其向下传递即可。将资源保存在using块中。如果您需要检查(大多数不需要),您可以定期致电ThrowIfCancellationRequested.
具体来说:
每次迭代都会等待某些事情发生,并可能启动一些异步任务。
如果您的“等待某事发生”是可取消的,并且您的“启动一些异步任务”是可取消的,那么只需将取消令牌传递给这两个方法即可。无需进行轮询。
或者我应该只调用 ThrowIfCancellationRequested 作为 StopAsync 的最后一行?
StopAsync如果您正在使用,请不要使用ExecuteAsync。
| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |