Sunday 13 November 2016

.Net High Performance Part 2 : Create Facade Tasks for External I/O or API calls

In the earlier module , I have explained how to create a Task object and delegate the work responsibility to separate thread of the application. It is more or less identified as a code Task because there is a specific set of code that existing which is responsible for the parallel execution.

But, what if there is a situation where we do not have a specific code to execute parallel instated we have an API call or some I/O operation to execute and yield the result ? We can use the Facade Tasks to solve these kind of operations.

Following is a very simple example of how to write a Facade Task to make a parallel Async API call.

The Sample application is to download stock data from various stock data sources ( Yahoo,MSN and Nasdaq). We are going to call all these 3 sources and Yield results from the first source which would return data.


 
 Task t_yahoo = GetDataFromYahooAsync(symbol, numYearsOfHistory);
 Task t_nasdaq = GetDataFromNasdaqAsync(symbol, numYearsOfHistory);
 Task t_msn = GetDataFromMsnAsync(symbol, numYearsOfHistory);

 
 Task[] tasks = { t_yahoo, t_nasdaq, t_msn };
 int index = Task.WaitAny(tasks); // proceed when at least one Task is completed.

 Task winner = tasks[index];

 foreach (Task t in tasks)  // cancel outstanding requests:
  if (t != winner)
  (t.AsyncState as RequestState).Request.Abort();

 return winner.Result;


So the Async Methods are as follows 



 
private static Task GetDataFromYahooAsync(string symbol, int numYearsOfHistory)
{
   // Create the required URL 
   HttpWebRequest WebRequestObject = (HttpWebRequest)HttpWebRequest.Create(url);

   RequestState state = new RequestState(
    WebRequestObject,
    string.Format("http://finance.yahoo.com, daily Adj Close, {0} years", numYearsOfHistory),
    new char[] { ',' },
    6 /*Adj Close*/
   );
    IAsyncResult iar = WebRequestObject.BeginGetResponse(new AsyncCallback(WebResponseCallback), state);

    // create Task facade, containing asyncstate so we cancel if necessary:
    state.TaskSource = new TaskCompletionSource(iar.AsyncState);
    return state.TaskSource.Task;

}

The TaskCompletionSource is the important class here which is responsible for creating the Facade Task.

No comments:

Post a Comment