how to handle 10 webrequests with Task.Any when the bandwhich is too slow
I'm querying asynchronously 10 webrequests using httpClient.GetAsync and
I'm using Task.Any to process data as soon as one of the 10 request
finished downloading
the thing is, each 10 request takes around 2-3 seconds to download and
using Task.Any means my app is downloading in the same time the 10
webrequests
if my connection bandwidth is slow the processing of the data is delayed
the solution would be to download a few requests, for example 2 out of the
10 requests and sleep the other 8 requests. Then keep waking up the rest
of the webrequest while process the first webrequests.
I don't know how I would do it for now, my code looks like this
private async void OnLaunchClick(object sender, RoutedEventArgs e)
{
var quotesTask = new List<Task<IEnumerable<Symbol>>>();
for (int i = 0; i < userInput.Symbols.Count(); i = i +
SYMBOLS_PAGINATION_PER_REQUEST)
{
var input = new
UserInput(userInput.Symbols.Skip(i).Take(SYMBOLS_PAGINATION_PER_REQUEST),
userInput.StartDate, userInput.EndDate,
userInput.Interval);
quotesTask.Add(quotesQuery.GetSymbolsInternal(input,
_cts.Token));
}
while (quotesTask.Count > 0)
{
Task<IEnumerable<Symbol>> quotesFinishedTask = await
Task.WhenAny(quotesTask);
quotesTask.Remove(quotesFinishedTask);
// Update UI
}
}
public async Task<IEnumerable<Symbol>> GetSymbolsInternal(UserInput
filteredInput, CancellationToken token)
{
if (filteredInput == null) throw new
ArgumentNullException("filteredInput");
string url = BuildUrl(filteredInput);
logger.Debug(string.Format("Start downloading quotes: {0}\n{1}",
filteredInput.Symbols.Select(a =>
a.Name).Join(","),
url));
string content = await _webRequest.GetData(url,
token).ConfigureAwait(false);
logger.Debug(string.Format("End downloading quotes: {0}",
filteredInput.Symbols.Select(a => a.Name).Join(",")));
var symbols = Parse(filteredInput.Symbols, content);
return symbols;
}
public class WebRequest
{
private static readonly Logger logger =
LogManager.GetCurrentClassLogger();
public virtual async Task<string> GetData(string uri,
CancellationToken token)
{
string result = string.Empty;
using (var client = new HttpClient())
using (var response = await client.GetAsync(uri,
token).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
result = await
response.Content.ReadAsStringAsync().ConfigureAwait(false);
else
logger.Error("Unable to retrieve data from the following
url: {0} - StatusCode: {1}", uri, response.StatusCode);
}
return result;
}
}
The goal is to speed up the download of 1 of the 10 webrequests in order
to process the data and to update UI as soon as possible instead of
downloading 10 webrequests in the same time with a limited bandwidth and
have to update the UI several seconds later.
No comments:
Post a Comment