如何用SignalR从blazor组件中取消Hub中长时间运行进程的异步任务



在blazor类中,我正在调用带有取消令牌的集线器异步方法,点击

tokensource = new CancellationTokenSource();
token = tokensource.Token;
await _hubConnection.SendAsync("MachineOperationOnServer", MachineID, cancellationToken:token).ConfigureAwait(false);

点击按钮,我正在取消CancellationTokenSource

tokensource.Cancel();

在hub类中,方法是

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);                    
}
});
}

有一些异步方法,它们在C#代码中提供了一个状态机和方便的回调约定。。。但我要建议的是异步请求。。。其中服务器接收请求并在请求的工作完成之前返回确认。

创建一个类来保存相关性。这将是对长时间运行的任务、请求id和可用于取消任务的任务完成源的引用。

当客户端调用以启动长期运行的任务时,服务器会创建一个Correlation实例,为其分配一个唯一的ID(我建议Guid.NewGuid(((,启动任务(向其传递ID和取消令牌(,然后将相关性存储在以后可以找到的位置:我建议使用Dictionary<Guid,相关性>。然后服务器返回id。这个id是您的请求id(有时也称为不透明标识符,如果客户端不应该对它做任何事情,而是在未来的相关调用中盲目使用它(。

现在,当服务器进程运行完毕时,需要将其自身从字典中删除,并且需要向服务器集线器添加一个新的cancel方法,以便客户端可以请求取消。如果客户端请求取消,则必须传递请求id,然后服务器可以查找相关性,并通过对任务完成源调用cancel来取消任务。取消后,您还应该从字典中删除相关性。

如果你需要一个返回结果,这会更复杂,但我会让你自己来决定。这种类型的编码有很多问题,您还需要担心访问字典时的线程安全问题。

相关内容

  • 没有找到相关文章

最新更新