I need to get some data from external service and store them in cache but it takes some time. Sometimes the request is quite long.
I'd like to throw TimeoutException and inform user that it is required to wait couple of seconds and retry the request but method which is responsible for collecting data should continue it's work in background.
Let's assume that I have a method:
public Task<CustomEntity> GetCustomEntity()
{
// time consuming task e.g call to external service
return result;
}
Next:
public async Task<CustomEntity> SomeMethod()
{
return await GetCustomEntity();
}
I'd like to somehow measure execution time of GetCustomEntity()
and after defined time throw TimeoutException but I'd like to continue Method execution in background.
I tried to use Task.WaitAny
with Timeout parameter and to write some wrapper with cancellationToken but all of such solutions stop task execution in background.
Kind of solution is to run task again after timeout is achieved. e.g:
// Wrapper
var taskToRun = Task.Factory.StartNew(() => GetCustomEntity());
if (Task.WaitAny(new Task [] { taskToRun }, TimeSpan.FromMilliseconds(timeout)) < 0)
{
Task.WhenAll(taskToRun);
throw new TimeOutException();
}
But solution above is a bit silly. In described situation, there is another question. How to return value from wrapper if request fit in timeout.