DelegatingHandler зависает при возврате Task <HttpResponseMessage> - PullRequest
0 голосов
/ 20 декабря 2018

Это мой очень простой класс, который демонстрирует проблему:

public class SimpleHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return new Task<HttpResponseMessage>(
                        () => new HttpResponseMessage(HttpStatusCode.Unauthorized));

            //return base.SendAsync(request, cancellationToken);
        }
    }

Ожидаемое поведение - ответ 401.Если я отлаживаю его, выполнение прибывает в оператор return и продолжается, когда я нажимаю F5, но http-запрос никогда не возвращается, и http-клиент заканчивает ожиданием тайм-аута.

Я действительно запутался, потому что я делаю то, что говорит мне компилятор: верните Task<HttpResponseMessage>.Вызов base.SendAsync работает просто отлично.Что мне здесь не хватает?

Редактировать:

Хорошо, так что я обнаружил, что

return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));

работает, как ожидалось.Тем не менее, я хотел бы понять, почему вышеуказанный подход не работает?В обоих случаях я создаю Task<HttpResponseMessage> Почему я получаю ожидаемое поведение только во втором случае?

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

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

И поскольку вы только создали задачу в своем примере и не вызывали Start(), она будет иметь статус Created и никогда не завершится сама по себе, так как не будет запущена.Следовательно, ваш процесс зависает, потому что дальше по конвейеру система будет ждать завершения задачи.

Вторая задача, созданная с помощью FromResult, представляет задачу, которая была завершена и в результате которой заданное значение,

Проверьте де Status свойство обоих Task и отметьте различия.(Создано против RanToCompletion)

Поскольку у вас нет реальной работы, вам следует придерживаться FromResult.

0 голосов
/ 20 декабря 2018

Вы можете использовать статический метод Task.FromResult, который используется для создания Задачи, которая является оболочкой для определенного значения:

Task.FromResult<HttpResponseMessage>(new HttpResponseMessage(HttpStatusCode.Unauthorized));
...