我知道,这里有很多关于 CancellationToken 的答案,但对于我的问题,我还没有找到任何解决方案。我只想在用户开始新的呼叫时取消此呼叫:
[HttpGet]
[Route("getUsers")]
public async Task<IEnumerable<string>> GetUsersAsync(string query)
{
return await _userService.GetUsersAsync(query);
}
我发现了类似的东西,但我不知道cancelToken从哪里来,也不知道我必须从这里传递它:
[HttpGet]
[Route("getUsers")]
public async Task<IEnumerable<string>> GetUsersAsync(string query, CancellationToken cancellationToken)
{
return await _userService.GetUsersAsync(query, cancellationToken);
}
当用户开始新的通话时,我只想取消此通话
在 Web API 中没有一个好的方法可以做到这一点,因为 Web API 通常是无状态的。因此没有(好的)方法来检测“用户何时开始新的”。
这通常是在客户端完成的,其中“当用户启动新的”很容易检测到。旧请求被取消并发出新请求。
您的 Web API 只需使用
CancellationToken
即可检测到请求被取消。取消令牌由 ASP.NET 提供,并在取消请求时触发。
要响应取消请求,最常见的模式是将其传递给您调用的任何 API。在这种情况下,您的
GetUsersAsync
调用将采用 CancellationToken
并将其传递给它使用的任何数据库 API。
控制器:
[HttpGet]
[Route("getUsers")]
public async Task<IEnumerable<string>> GetUsersAsync(string query)
{
var token = HttpContext.RequestAborted;
return await _userService.GetUsersAsync(query, token);
}
服务:
public class UserService: IUserService
{
private readonly ConcurrentDictionary<string, CancellationTokenSource> _usersTokens;
public UserService()
{
_usersTokens = new ConcurrentDictionary<string, CancellationTokenSource>(64, 64);
}
public async Task GetUsersAsync(string query, CancellationToken token)
{
CancellationTokenSource tokenSource;
if (_usersTokens.TryGetValue(query, out tokenSource))
{
tokenSource.Cancel();
tokenSource.Dispose();
tokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
_customerIds.AddOrUpdate(query, tokenSource, (key, oldValue) => tokenSource);
}
else
{
tokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
_usersTokens.TryAdd(query, tokenSource);
}
// your code
}
}