HttpClient.GetAsync зависает, затем интернет исчезает во время его выполнения

Вы можете использовать оператор $in для соответствия любому из значений в массиве:

db.users.find(
    {email : {$in : ["mail7@domain.com", "mail117@domain.com", "mail 987@domain.com"]}}
)

0
задан Ultra 16 January 2019 в 17:28
поделиться

1 ответ

Я не уверен на 100% в том, что ты пытаешься сделать, но в твоем LimitedTimeAwaiter есть недостаток. Вы на самом деле не передаете originalToken HttpClient, поэтому он не будет использоваться для отмены. Чтобы это исправить, вы должны связать свои два токена:

public class LimitedTimeAwaiter<T>
{
    public static async Task<T> Execute(Func<CancellationToken, Task<T>> function, CancellationToken originalToken, int awaitTime)
    {
        originalToken.ThrowIfCancellationRequested();

        var timeout = CancellationTokenSource.CreateLinkedTokenSource(originalToken);
        timeout.CancelAfter(TimeSpan.FromSeconds(awaitTime));

        try
        {
            return await function(timeout.Token);
        }
        catch (OperationCanceledException err)
        {
            throw new Exception("LimitedTimeAwaiter ended function ahead of time", err);
        }
    }
}

(также не совсем понятно, почему вы поймали исключение, но это не относится к делу).

Теперь я собираюсь предположить, что ваша проблема в том, что задание, возвращаемое HttpClient, не завершается, даже когда вы отменяете правильный токен. Во-первых, вы должны сообщить об этом, потому что это будет ошибкой в ​​реализации HttpClient. Затем вы можете использовать этот обходной путь:

public class LimitedTimeAwaiter<T>
{
    public static async Task<T> Execute(Func<CancellationToken, Task<T>> function, CancellationToken originalToken, int awaitTime)
    {
        originalToken.ThrowIfCancellationRequested();

        using (var timeout = CancellationTokenSource.CreateLinkedTokenSource(originalToken))
        {
            timeout.CancelAfter(TimeSpan.FromSeconds(awaitTime));

            try
            {
                var httpClientTask = function(timeout.Token);
                var timeoutTask = Task.Delay(Timeout.Infinite, timeout.Token); // This is a trick to link a task to a CancellationToken

                var task = await Task.WhenAny(httpClientTask, timeoutTask);

                // At this point, one of the task completed
                // First, check if we timed out
                timeout.Token.ThrowIfCancellationRequested();

                // If we're still there, it means that the call to HttpClient completed
                return await httpClientTask;
            }
            catch (OperationCanceledException err)
            {
                throw new Exception("LimitedTimeAwaiter ended function ahead of time", err);
            }
        }
    }
}
0
ответ дан Kevin Gosse 16 January 2019 в 17:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: