如何在Blazor组件中通过SignalR取消Hub中的长运行异步任务
如何取消SignalR Hub中的长运行异步任务
问题场景
在Blazor组件中,点击按钮时通过取消令牌调用Hub异步方法:
tokensource = new CancellationTokenSource(); token = tokensource.Token; await _hubConnection.SendAsync("MachineOperationOnServer", MachineID, cancellationToken:token).ConfigureAwait(false);
点击取消按钮时触发取消操作:
tokensource.Cancel();
但当前Hub中的MachineOperationOnServer方法无法响应取消请求,原代码如下:
public async Task MachineOperationOnServer(int machineID) { await Task.Factory.StartNew(async () => { int progressPer = 0; for (int i = 1; i < 20; i++) { progressPer = Convert.ToInt32(((decimal)i / 20) * 100); await Clients.Client(Context.ConnectionId).SendAsync("ProgressOnClient", progressPer); Thread.Sleep(1000); } }); }
解决方案
要实现取消长运行任务,需从以下三点修改代码:
将取消令牌传入Hub方法
SignalR支持在调用Hub方法时自动传递取消令牌,只需修改Hub方法的签名,添加CancellationToken参数:public async Task MachineOperationOnServer(int machineID, CancellationToken cancellationToken)替换阻塞操作并检查取消令牌
- 用
await Task.Delay(1000, cancellationToken)替代Thread.Sleep(1000):Thread.Sleep是同步阻塞操作,无法响应取消信号;Task.Delay支持传入取消令牌,会在令牌触发取消时抛出OperationCanceledException。 - 在循环的每一步主动检查取消令牌,确保任务能及时终止。
- 用
修正异步任务的创建方式
原代码中Task.Factory.StartNew(async () => { ... })会返回嵌套的Task<Task>,直接await会导致外层任务提前完成,内部异步操作脱离管控。直接去掉不必要的任务包装即可,因为Hub方法本身就是异步方法,SignalR会在后台线程处理调用。
修改后的Hub方法完整代码:
public async Task MachineOperationOnServer(int machineID, CancellationToken cancellationToken) { int progressPer = 0; for (int i = 1; i < 20; i++) { // 主动检查取消令牌,若已取消则抛出异常终止任务 cancellationToken.ThrowIfCancellationRequested(); progressPer = Convert.ToInt32(((decimal)i / 20) * 100); // 向客户端发送进度时也传入取消令牌,确保发送操作可被取消 await Clients.Client(Context.ConnectionId).SendAsync("ProgressOnClient", progressPer, cancellationToken); // 使用支持取消的Task.Delay替代同步阻塞的Thread.Sleep await Task.Delay(1000, cancellationToken); } }
关键说明
- Blazor端调用
SendAsync时传入的取消令牌,会自动传递给Hub方法的CancellationToken参数,无需额外处理。 - 当调用
tokensource.Cancel()时,取消令牌会触发ThrowIfCancellationRequested()或Task.Delay抛出OperationCanceledException,从而立即终止循环和整个任务。 - 不需要额外创建嵌套异步任务,Hub方法本身的异步逻辑会被SignalR正确调度。
内容的提问来源于stack exchange,提问作者Ovais
相关产品推荐
相关产品推荐

