Как установить тайм-аут или ограничить время ожидания ответа от внешнего API

Я сталкивался с этой проблемой в целом и так и не решил ее, но сегодня утром у меня есть конкретный случай.

Мои приложения интегрируются с API доставки Despatch Bay: https://github.com/despatchbay/despatchbay-api-v15/wiki

Я не буду беспокоить вас со всем кодом, но сегодня утром их конечные точки выходят из строя, и я получаю сообщение об ошибке в этой строке моего кода, которая запрашивала службы доставки из их API в соответствии с данными посылки, которые я отправляю ему:

Dim Services As dbShipping.ServiceType() = DespatchBay.Services.Get(Company, Box.ToParcel(ParcelValue:=ParcelTotal), DBRecipient)

Их код также не работает на их собственном веб-сайте.

Я временно преодолел эту проблему, заключив код, требующий указанного выше объекта Services, в Try/Catch, но на самом деле требуется довольно много времени, чтобы вывести его из строя.

Итак, как мне вместо того, чтобы писать:

Try
     Dim Services As dbShipping.ServiceType() = DespatchBay.Services.Get(Company, Box.ToParcel(ParcelValue:=ParcelTotal), DBRecipient)
Catch
    ' Do stuff it broke
End Try

Напишите что-нибудь вроде

Wait for Despatch Bay:    
    Dim Services As dbShipping.ServiceType() = DespatchBay.Services.Get(Company, Box.ToParcel(ParcelValue:=ParcelTotal), DBRecipient)
But if it takes too long
    'Do stuff, it broke
End waiting for Despatch Bay

Я хочу только тайм-аут ответа от этого запроса API, а не весь блок кода.

Если это важно, я ищу .NetStandard решение, а не конкретное для Framework.


person Jamie Hartnoll    schedule 10.10.2020    source источник


Ответы (1)


Я нашел этот вопрос, который задают здесь аналогичным образом:

Установить тайм-аут для операции

Мое выбранное решение:

using System.Threading.Tasks;

var task = Task.Run(() => obj.PerformInitTransaction());
if (task.Wait(TimeSpan.FromSeconds(30)))
    return task.Result;
else
    throw new Exception("Timed out");

Преобразованный в VB и ожидающий, что моя функция вернет объект, мой фактический код:

Dim Services As dbShipping.ServiceType()
Dim ServicesTask As Task(Of dbShipping.ServiceType()) = Task.Run(Function() DespatchBay.Services.Get(Company, Box.ToParcel(ParcelValue:=ParcelTotal), DBRecipient))
If ServicesTask.Wait(TimeSpan.FromSeconds(5)) Then
    Services = ServicesTask.Result
Else
    Log.Report("It took too long to get dispatch bay records so abandon", TLog.Level.Warning)
End If
person Jamie Hartnoll    schedule 10.10.2020