『技术群里聊些啥』Task 不是你想 Cancel,想 Cancel 就能 Cancel
source link: https://blog.51cto.com/MyIO/5283532
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
『技术群里聊些啥』Task 不是你想 Cancel,想 Cancel 就能 Cancel
原创在群里看到有人问如何取消这个 Task 的执行:
实际上这并不会取消S1eepMode1
方法的执行:
这是为什么呢?
首先,让我们看看s_cts.Cancel()
都做了啥:
public void Cancel(bool throwOnFirstException)
{
ThrowIfDisposed();
NotifyCancellation(throwOnFirstException);
}
private void NotifyCancellation(bool throwOnFirstException)
{
// If we're the first to signal cancellation, do the main extra work.
if (!IsCancellationRequested
&& Interlocked.CompareExchange(ref _state, NotifyingState, NotCanceledState) == NotCanceledState)
{
...
}
}
实际上,Cancel
方法仅仅是将变量_state
的值改为NotifyingState
。那Task.Run
传递s_cts.Token
又有什么用呢?
{
if (function == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.function);
// Short-circuit if we are given a pre-canceled token
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled<TResult>(cancellationToken);
...
}
原来,是在创建 Task 前先检查令牌是否已经Cancel,以便快速终止。
那么,到底怎么才能Cacel
已创建的Task
呢?
其实,Task.Run
的方法实现已经告诉我们正确的解决方案,那就是判断cancellationToken.IsCancellationRequested
:
{
while (true)
{
if (cancellationToken.IsCancellationRequested)
return;
...
}
}
另外,也可以采取抛出异常的方式:
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
...
}
}
示例应用程序并不会捕获到这个异常,相关问题可以看我以前的文章《 如何保证执行异步方法时不会遗漏 await 关键字》
在创建 Task 时请记住,即使你执行了令牌取消操作,也并不意味着 Task 会停止运行。
- 赞
- 收藏
- 评论
- 分享
- 举报
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK