I need to call the web service several times to get data, and then put those data into my database, so I've got the following code:
foreach (string v in options)
{
IList<MySampleNode> nodes = _pi.GetData(v);
_dbService.SaveToDb(nodes);
}
the GetData implementation looks as follows:
public IList<MySampleNode> GetData(string v)
{
IList<MySampleNode> nodes = null;
try
{
var client = new WsClient();
IEnumerable<IWsObject> wsNodes = client.getNodes(new getClassLevel { code = v });
nodes = ProcessData(wsNodes);
}
return nodes;
}
I'd like to modify this code to asynchronous version to run each download/save to database in separate thread and wait for all threads to be finished, or maybe there are some other approaches to improve the performance of such code, can you please help me?
This downloads all in parallel and stores them into the DB with one write.
This would initiate asynchronous call
This would wait for execution to complete and return value:-
To improve the scalability (i.e., the number of request your web app can serve simultaneously), you need to reduce the number of threads your app is using for each requests. So, instead of waiting for all threads to be finished, you should use naturally asynchronous APIs, which don't block a thread while the operation is pending. More details on this can be found here.
If you can use .NET 4.5, your specific case might be improved like this:
The client-side proxy for
WsClient
probably already has an async version ofgetNodes
, calledgetNodesAsync
(if not, check this).ProcessDataAsync
starts a bunch of parallel non-blockingGetDataAsync
tasks (for each node), and asynchronously awaits their completion. That's what makes this code scale well.You might be able to further improve
ProcessDataAsync
by saving the data asynchronously, i.e.await _dbService.SaveToDbAsync(nodes)
, if you can leverage the use of asynchronousTask
-based DB API (e.g, with EF6).