简体   繁体   中英

Multitasking multiple Class Instances

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 "";
}

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM