1

I have a simple collection which I'm looping through like this:

foreach (MyObject mo in myObjects)
{
   myObject.RunAcync();
}

RunAsync executes code in a separate thread, using new Thread(()=>{ .. }).Start(), it's not in my power to change the code of RunAsync. I need to limit the number of instances of myObject running concurrently to N (real numbers are 2..10). What is the efficient way to do that using .NET4 and c#?

user1514042
  • 1,899
  • 7
  • 31
  • 57
  • You problem is that how do you know how many of these RunAsync methods are still running or not? – Peter Ritchie Sep 10 '12 at 13:21
  • Yes, one of the problems, I've no Complete event fired by individual instances... – user1514042 Sep 10 '12 at 13:23
  • With no way to tell what is done and what is still running, I don't see how you do what you want without modifying `RunAsync`. – Peter Ritchie Sep 10 '12 at 13:25
  • @Peter Ritchie Makes sense, how would you go about this task if you implemented if from scratch? – user1514042 Sep 10 '12 at 13:26
  • Is there a non-async version of the method, e.g. `.Run()`. If so you could wrap that one with your own code to make it asynchronous. You could pass `myObject` to a method on some `RunScheduler` class, and `RunScheduler` kicks off the thread immediately and increments a count, unless the count is 20, in which case it adds them to a queue. You need to be able to see when they finish to deincrement the counter and kick off the next one in the queue. – Tim Goodman Sep 10 '12 at 13:29
  • With what we have now (.NET 4) and what's imminent (now when you think about it, .NET 4.5), I would use the Task Parallel Library (TPL) and return some sort of `Task` object from `RunAsync`. You can then easily tell what is done and what is running, and use the built-in TPL load balancing to limit the number of running tasks. – Peter Ritchie Sep 10 '12 at 13:30
  • @user1514042 Alternatively, if you had a non-async version of the method, you could also use the TPL's `Parallel.ForEach` to invoke the method and it would deal with load-balancing and run only enough of the methods at one time to avoid performance issues. – Peter Ritchie Sep 10 '12 at 13:32
  • @Peter Ritchie Thanks, could you post your comment as answer I'll mark it off. – user1514042 Sep 10 '12 at 13:35

1 Answers1

0

If you can modify RunAsync, with what we have now (.NET 4) and what's imminent (now when you think about it, .NET 4.5), I would use the Task Parallel Library (TPL) and return some sort of Task object from RunAsync. You can then easily tell what is done and what is running, and use the built-in TPL load balancing to limit the number of running tasks. Alternatively, if you had a non-async version of the method, you could also use the TPL's Parallel.ForEach to invoke the method and it would deal with load-balancing and run only enough of the methods at one time to avoid performance issues

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98