I have a method that should make a http call and should wait for response no longer that some timeout. If no response received within timeout time method should return empty string, BUT response must be processed later anyway.
async Task<string> GetResponseOrContinue(int timeout, Action<string> responseHandler)
{
var task = Task.Run(async () =>
{
var response = await _webClient.UploadStringTaskAsync("url", "");
responseHandler(response);
return response;
});
var emptyTask = Task.Run(async () =>
{
await Task.Delay(timeout);
return string.Empty;
});
return await await Task.WhenAny(task, emptyTask);
}
I omitted try/catches and other details for the sake of simplicity... This code seems to work but I stuck trying to test it.
I wrote test that works correctly almost always, but sometimes something goes wrong with this timeout stuff and test fails.
I mock UploadStringTaskAsync
call using Moq framework:
certWebClient.Setup(x => x.UploadStringTaskAsync(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(() =>
{
Thread.Sleep(timeout + 10);
return "this response will be received after timeout";
});
and then pass this timeout variable to GetResponseOrContinue
method. Looks pretty simple but it's not trustworthy...
What can go wrong here and maybe there more appropriate solution for such problem?