I am calling a service outside of my control. My application must include a time out, so that if the call to the service takes too long, an appropriate time-out message is returned.
// Client connected to remote service
RemoteClient Client = new RemoteClient();
private async Task<MyResult> CheckItAsync(CheckRequest rqst, int timeout)
{
// MyResult object gets some values populated on construction
MyResult Result = new MyResult()
// RemoteResponse auto generated from 'Add Service Reference'
RemoteResponse response;
try
{
// Perform the check and return the appropriate response.
var task = Client.PerformCheckAsync(rqst);
var res = await Task.WhenAny(task, Task.Delay(timeout));
if (res == task)
{
// Task completed within time.
response = task.GetAwaiter().GetResult();
// Populate my result object with the necessary values
Result.populate(response);
}
else
{
// Task timed out, populate result with timeout message
Result.timedOut(rqst.RequestNumber);
}
}
catch (Exception e)
{
// Something else happened, log exception and return failed result
Elmah.ErrorSignal.FromCurrentContext().Raise(e);
Result.failed(rqst.RequestNumber);
}
return Result;
}
I read that Task.WhenAny..
will still continue calling the service in the background even after the time out, creating a leak, but I am not sure how to stop the call as the remote service does not take a CancellationToken
.
The code works fine and returns the correct responses when it times out and when it doesn't.
*Additional follow-up question, does this code call the remote service multiple times? (at both var task = ...
and Task.WhenAny...
)