public void WorkerFinished(object obj, RunWorkerCompletedEventArgs args)
{
// See if any of the workers are reporting that they're out
// of results.
bool outOfResults = _pageManagers.Any(i => i.WorkStatus ==
PageManager.Status.NoResults);
// If so, don't deploy another thread.
if (outOfResults)
{
string msg = "PageManager reporting no more results;";
msg += " not deploying another thread.";
Debug.WriteLine(msg);
return;
}
// Or if there are no threads that are marked "Working",
// we are done
if (IsWorkFinished())
{
HaltAllOngoingWork();
return;
}
if (args == null) return;
if (args.Error != null)
{
Debug.WriteLine(args.Error.Message);
return;
}
if (args.Result == null ||
args.Result.GetType() != typeof(PageManager)) return;
// If this PageManager is done but we haven't hit our
// target number of results, we should spawn a new thread
PageManager finished = (PageManager)args.Result;
// Get the index of the PageManager whose search page number
// matches the one that just finished (we're going to replace
// it with a new PageManager)
int index =_pageManagers.ToList().FindIndex(i =>
i.PageNumber == finished.PageNumber);
// Increment the variable that tracks the
// highest page number we've searched so far
// TODO: since page number is shared state, there is a
// slight chance that two PageManagers might hit this
// code
_pageNumber += 1;
// Start searching a new page
PageManager newPageManager = new PageManager(
_pageNumber,
_searchCriteria,
Scraper.LoadSearchPage, // inject method for testing here
ResultReturned,
WorkerFinished);
_pageManagers[index].Dispose(); // get rid of old one
_pageManagers[index] = newPageManager;
_pageManagers[index].RunWorkerAsync();
}