0

I am having array of objects and i need them to be executed in a separate threads. I thought it is better to use asynchronous call begin/end.invoke but even though it is executing on a new thread, it is waiting to one thread's callback returns. But i need to fire all the object on different threads at once.

But my another concern is if i create a thread for each object it will be costly. Please let me know the best way to perform this task.

Below is the assync method i have tried,

object[10] objs = new objects[];
foreach (object o in objs)
{
    // method needs to process ASAP
    StartProcessing(o);
}

void StartProcessing(object o)
{
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
FatalError
  • 77
  • 2
  • 9

3 Answers3

2

Since there are no any special requirements for firing a method in the question, I can't see any reason, why QueueUserWorkItem won't fit:

foreach(object o in objs)
{
    // start processing is a return void method needs to process ASAP
    var v = o;
    ThreadPool.QueueUserWorkItem(_ => StartProcessing(v));
}
Dennis
  • 37,026
  • 10
  • 82
  • 150
  • do i need to worry about terminate terminating thread at the end or it will terminate itself once its completed. – FatalError May 24 '14 at 19:26
  • This will be a thread pool worker thread. When your method will return, the thread will back into thread pool. You don't need to worry about the thread lifetime, neither when starting work item, nor when finishing it - this is thread pool work. – Dennis May 24 '14 at 19:34
  • Thanks. one more requisition. if the StartProcessing method/whole execution is thread safe, are there anything else that need to be considered when we are running it on a new threads. – FatalError May 24 '14 at 19:41
  • 1
    That's not going to work because of the closure of the 'o' parameter. – Bartosz Wójtowicz May 24 '14 at 19:50
  • In case, when processing of particular item is independent from another items, no, there are no things to consider else. – Dennis May 24 '14 at 19:58
  • Can you please elaborate the closure . i am not getting it. why we want it to assign another variable. – FatalError May 24 '14 at 22:07
  • "Starting with the .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code." http://stackoverflow.com/a/10906556/2189576 – shfire May 25 '14 at 04:43
  • About closure http://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp – shfire May 25 '14 at 04:50
  • @Dennis why it is required to assign to var variable. Is there a chance for any delay when we used ThreadPool.QueueUserWorkItem than creating a new thread. because i feel there is some delay. – FatalError May 26 '14 at 17:51
  • @shfire: and now look at the question tags more attentively. – Dennis May 27 '14 at 10:46
  • @FatalError: assigning of a variable is required because of closure of loop variable (before C# 5). Here's detail explanation from Eric Lippert: http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx. – Dennis May 27 '14 at 10:58
  • @FatalError: About delay: thread pool doesn't starts `objs.Length` threads. It creates an optimal number of threads for the particular environment, which depends on number of CPU's and CPU cores. That's why work item is being queued - if there are no available threads, the work item just waits. If you have 4 CPU cores on a single CPU, then you shouldn't create 100 threads to process 100 items. It wouldn't be faster from 4 threads. – Dennis May 27 '14 at 10:59
  • @Dennis i believe the closure is required if we are using lamda expressions. otherwise it seems fine. – FatalError May 27 '14 at 18:53
  • @Dennis since i know the exact threads i required before i fire them. can i use SetMinThreads and set it to some average number of threads. Is it become faster then. like if i need 5 thread, just before firing them i will set SetMinThreads =10 . and then use threadpool thread . is it fine? – FatalError May 27 '14 at 19:01
  • @FatalError: `ThreadPool` is quite optimized for common scenarios. I'd recommend to not to use `SetMinThreads`. "I know the number of threads I need" is a wrong way. System resources is the primary thing. – Dennis May 28 '14 at 04:45
0

You can achieve that using tasks.

    object[] objs = new object[10];
    List<Task> tasks = new List<Task>();
    foreach (object o in objs)
    {
        // method needs to process ASAP
        var localObj = o;
        tasks.Add(Task.Factory.StartNew(() => StartProcessing(localObj)));
    }

    try
    {
        Task.WaitAll(tasks.ToArray());
    }
    catch (AggregateException ae)
    {
        // handle the exceptions
    }
Bartosz Wójtowicz
  • 1,321
  • 10
  • 18
0

You can use Parallel.ForEach, it will start Task for each element in array, and synchronously return when all Task's are finished.

Parallel.ForEach(objs, StartProcessing);
shfire
  • 837
  • 7
  • 7