Question

Today I decided to try out multi-Tasking to see if I get a performance improvement compared to multi-Threading. Im especially interested because Im looking for an easy way to return values and and use features like WaitAll or WaitAny. My question is what am I doing wrong and what is the best way to multitask multiple Instances?

Here is my old code using Threads. (Working)

Thread[] threads = new Thread[5];
ScrapeFollowersIds[] scrapeClass = new ScrapeFollowersIds[5];
for (int i = 0; i < 5; i++)
{
  scrapeClass[i] = new ScrapeFollowersIds();
  threads[i] = new Thread(() => scrapeClass[i].ScrapeFollowers(cookie,proxy);
  threads[i].Start();
}

And here is my new solution.

Every Task shows me Status = Faulted, Method {null}, Result not yet computed Looking at the exception I get Inner Exception: Index was outside the bounds of the Array

Task<string>[] scrapeFollowers = new Task<string>[5];
ScrapeFollowersIds[] scrapeClass = new ScrapeFollowersIds[5];
for (int i = 0; i < 5; i++)
{
  scrapeClass[i] = new ScrapeFollowersIds();
  scrapeFollowers[i] = Task<string>.Factory.StartNew(() => 
                         scrapeClass[i].ScrapeFollowers(cookie, proxy);
}

The method Im calling looks like this

try
{  
  //Dosomething 
  return someString;
} 
catch
{
  return "";
}
Was it helpful?

Solution

You're closing over the loop variable, i.

The bug actually exists in both programs.

Since the lambda defining the code to run in another thread closes over i, and i ends up being (potentially) changed by the main thread before the code actually runs. Take a copy of the loop variable inside of the loop and close over that.

Having said that, you can avoid the entire situation entirely using the TPL by not creating an external array that all of the tasks need to manually access. It's not a very TPL oriented way of doing things. Instead have each task independently create its result, and then aggregate the results:

var tasks = Enumerable.Range(0, 5)
    .Select(_ => Task.Run(() => CreateScrapeFollower(cookie, proxy)));

var results = Task.WhenAll(tasks);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top