Reputation: 97
I have a piece of code that execute HTTP requests (inside a loop) from some currency API and do some work on the data which received.
Because it was slow, I changed it to asynchronously function using: Task.Run()
However, when I measure calculation time (using Stopwatch..) of the function with the async method, it takes more time (or even) than the sync one.
How can it possible? Am I do it wrong?
[HttpPost,Route("GetCurrenciesData")]
public IHttpActionResult GetCurrenciesData(InputCurrenciesData cls)
{
try
{
var watch = Stopwatch.StartNew();
var data2 = GetBL.mySyncMethod(cls.currenciesList);
watch.Stop();
string first = watch.Elapsed.ToString(); // --> this faster
watch = Stopwatch.StartNew();
var data = GetBL.myAsyncMethod(cls.currenciesList);
string second = watch.Elapsed.ToString(); // --> this slower
return Ok(data);
}
catch (Exception ex)
{
getGeneric.WriteError(ex.Message, ex.StackTrace);
return BadRequest();
}
}
Example code of the sync function:
public GenericClass mySyncMethod(string[] currencies)
{
try
{
foreach (string currency in currencies)
{
getDataFromApi(currency);
}
return getDataChart;
}
catch (Exception ex)
{
WriteError(ex.Message, ex.StackTrace);
return null;
}
}
Example of the async :
public GenericClass myAsyncMethod(string[] currencies)
{
try
{
List<Task> TaskList = new List<Task>();
foreach (string currency in currenies)
{
var myTask = new Task(() =>
{
getDataFromApi(currency);
});
myTask.Start();
TaskList.Add(myTask);
}
Task.WaitAll(TaskList.ToArray());
return getDataChart;
}
catch (Exception ex)
{
WriteError(ex.Message, ex.StackTrace);
return null;
}
}
The code of the function getDataFromApi:
private void getDataFromApi(string currency)
{
string currencyCode = getCurrenciesDictionary[currency];
//Get api's URL from Web.config and concatenation the wanted currency code
string URL = string.Format(GetConfig("Api"), currencyCode);
/*HTTP request to retrieve data from Api*/
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.UseDefaultCredentials = true;
using (HttpClient httpClient = new HttpClient(handler))
{
var ResultAsync = httpClient.GetAsync(URL).Result;
if (ResultAsync.IsSuccessStatusCode)
{
var content = ResultAsync.Content;
string Data = content.ReadAsStringAsync().Result;
try
{
var ret = JsonConvert.DeserializeObject<RootObject>(Data);
/*add new class to currencyRate list - class which represent the currency and its rates*/
getDataChart.CurrencyRate.Add(new CurrencyRate
{
Currency = currency,
Rates = ret.dataset.data.AsEnumerable().
Select(date => Double.Parse(date[1].ToString())).ToList()
});
}
catch (Exception ex)
{
WriteError(ex.Message + " currency: " + currency + "/n/ URL: " + URL, ex.StackTrace);
}
}
}
}
Upvotes: 1
Views: 1951
Reputation: 1706
try and read some of this guy:
he's telling in a few words how it works. The main point is that you get some overhead using async/await, however, you're freeing resources. So any task that will run, will run on the synchronized context. but you can handle much more request.
Besides the fact that you are not really using async functionality with the .result
kills actually the async part.
In a short line, doing it async doesn't necessarily speed it up. If you have more CPU-bound tasks, that can run simultaneously you will major performance, however, in your case, you will not performance, but resources like Kevin tells in his comments.
hope it helps!
Upvotes: 3