取消不可取消的任务

剑圣开发

我在代码库中有以下代码:

public async Task<HttpApiResponse> FindUsers(Guid userId)
{
    try
    {
        AccessToken token = tokenService.GetAccessToken();
        channel = channelFactory.CreateChannelWithToken(token);
        HttpApiResponse response = await channel.FindUsers(request);

        return response.ToDto();
    }
}

现在我喜欢在这里使用 CancellationToken,但我不太确定我是否做得对:

public async Task<HttpApiResponse> FindUsers(Guid userId, CancellationToken ct)
{
    try
    {
        var taskCompletionSource = new TaskCompletionSource<decimal>();

        ct.Register(() =>
        {
            // We received a cancellation message, cancel the TaskCompletionSource.Task
            taskCompletionSource.TrySetCanceled();
        });

        AccessToken token = await tokenService.GetAccessToken();
        
        await Task.WhenAny(token, taskCompletionSource.Task).ContinueWith(async token => 
        {
            channel = channelFactory.CreateChannelWithToken(token);
            HttpApiResponse response = await channel.FindUsers(request);

            return response.ToDto();
        });   
    }
}

我不确定的原因是因为我不太确定我应该如何处理await channel.FindUsers(request);内部ContinueWith我是否需要处理它,因为我在获取令牌时已经处理了它?

毫米8

您无法真正取消不支持取消的 API,但您可以使用TaskCompletionSourceFindUsers在调用之前从您的方法返回GetAccessTokenFindUsers完成(如果这是您想要的)。

OperationCanceledException如果在CancellationToken当前实现/重载FindUsers返回值之前被取消,下面的重载将抛出一个

public async Task<HttpApiResponse> FindUsers(Guid userId, CancellationToken ct)
{
    var taskCompletionSource = new TaskCompletionSource<decimal>();
    using (ct.Register(() => taskCompletionSource.TrySetCanceled()))
    {
        var findUsersTask = FindUsers(userId);
        await Task.WhenAny(findUsersTask, taskCompletionSource.Task);
        ct.ThrowIfCancellationRequested();
        return findUsersTask.Result;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章