简体   繁体   中英

How to timeout, or limit the waiting time for a response from an external API

I have come across this problem generally and never really resolved it, but this morning I have a specific case.

My applications integrates with the Despatch Bay Shipping API: https://github.com/despatchbay/despatchbay-api-v15/wiki

I won't bother you with all the code, but this morning their endpoints are failing and I am getting an error on this line of my code, which requested shipping services from their API according to parcel data I send it:

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

Their code is also failing on their own website.

I have temporarily "overcome" this problem by wrapping the code that requires the Services object above in a Try/Catch but it takes quite a long time to actually fail.

So how do I, instead of writing:

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

Write something like

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

I only want to timeout the response from that API request, not my entire code block.

If it matters, I am looking for a .NetStandard solution, not a Framework specific one.

I have found this Question similarly asked here:

Set timeout to an operation

My chosen solution is:

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");

Converted to VB and expecting my function return an object, my actual code is:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM