Blazor CancellationToken 在组件中的使用方法

来源:这里教程网 时间:2026-02-21 17:39:07 作者:

Blazor 中的

CancellationToken
主要用于安全取消异步操作,避免组件已销毁或状态已变更时仍在执行无意义的耗时任务(比如 HTTP 请求、定时器、长循环等),防止内存泄漏、UI 异常或陈旧数据覆盖。

在 OnInitializedAsync 中使用 CancellationToken

组件初始化时发起异步加载是最常见场景。Blazor 会自动将当前生命周期的取消令牌传入

OnInitializedAsync
,你只需接收并传递给 awaitable 方法即可:

protected override async Task OnInitializedAsync()
{
    try
    {
        // dataService.GetDataAsync 自动支持 CancellationToken
        items = await dataService.GetDataAsync(cancellationToken);
    }
    catch (OperationCanceledException)
    {
        // 被取消时静默处理(通常无需报错)
    }
}

注意:必须确保底层方法(如

HttpClient.GetAsync
或自定义服务)真正接收并响应该 token,否则取消无效。

手动管理 CancellationTokenSource(适用于动态触发)

当操作由用户交互(如搜索框输入、按钮点击)触发,且需支持“取消前一个请求、发起新请求”时,应手动创建

CancellationTokenSource
并及时释放:

在组件字段中声明:
private CancellationTokenSource? _cts;
每次触发新操作前,先调用
_cts?.Cancel(); _cts?.Dispose();
,再新建
_cts = new();
_cts.Token
传给异步方法
Dispose
方法中调用
_cts?.Cancel(); _cts?.Dispose();
防止残留

示例(搜索建议):

private async Task OnSearchInputChanged(string value)
{
    _cts?.Cancel();
    _cts?.Dispose();
    _cts = new();
    if (!string.IsNullOrWhiteSpace(value))
    {
        suggestions = await searchService.GetSuggestionsAsync(value, _cts.Token);
    }
}
public void Dispose()
{
    _cts?.Cancel();
    _cts?.Dispose();
}

监听组件销毁自动取消(关键保障)

Blazor 会在组件被移除 DOM 时调用

Dispose
,但默认不自动触发取消。你需要显式绑定生命周期事件:

OnInitialized
OnParametersSet
中注册:
Disposal.Register(() => _cts?.Cancel());
或重写
Dispose(bool disposing)
(推荐,尤其在继承
ComponentBase
的基类中统一处理)
确保所有长期运行的异步操作都接受 token,并在
catch (OperationCanceledException)
中正确退出,不更新状态

未响应取消的代码(如没传 token、忽略异常、仍调用

StateHasChanged()
)会导致“对象已释放”异常或 UI 错乱。

常见误区提醒

不要在非 async 方法中直接调用

token.ThrowIfCancellationRequested()
—— 这会抛出异常但无法被 Blazor 的异步上下文捕获,可能中断渲染流程。
不要复用同一个
CancellationToken</strong> 实例跨多次独立操作 —— 它是一次性的,取消后不可重置。<br>
<strong>不要依赖 <code>IsCancellationRequested
轮询代替真正异步取消
—— 对 I/O 操作无效,且消耗 CPU。

基本上就这些。核心就两点:让异步调用真正“听” token,让 token 在组件消亡时“准时失效”。

相关推荐