2

First of all I am totally new to threading in C#. I have created multiple threads as shown below.

if (flag)
{
    foreach (string empNo in empList)
    {
         Thread thrd = new Thread(()=>ComputeSalary(empNo));
         threadList.Add(thrd);
         thrd.Start();
    }
}

Before proceeding further I need check if at least one thread is completed its execution so that I can perform additional operations.

I also tried creating the list of type thread and by added it to list, so that I can check if at least one thread has completed its execution. I tried with thrd.IsAlive but it always gives me current thread status.

Is there any other way to check if atleast on thread has completed its execution?

dda
  • 6,030
  • 2
  • 25
  • 34
Chethan
  • 298
  • 1
  • 4
  • 17
  • 3
    You might want to consider switching from `Thread`s to [`Task`](http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx)s, which are a more modern way of parallelizing work. `Task`s also support a `WhenAny` method which pretty well fits for what you're asking for (but also support e.g. `ContinueWith` which may actually be closer to what you need, depending on what "additional operations" you're actually trying to perform) – Damien_The_Unbeliever Sep 29 '14 at 06:47

2 Answers2

3

You can use AutoResetEvent.

var reset = new AutoResetEvent(false); // ComputeSalary should have access to reset
.....
....

if (flag)
{
    foreach (string empNo in empList)
    {
         Thread thrd = new Thread(()=>ComputeSalary(empNo));
         threadList.Add(thrd);
         thrd.Start();
    }
    reset.WaitOne();
}

.....
.....

void ComputeSalary(int empNo)
{
    .....
    reset.set()
}

Other options are callback function, event or a flag/counter(this is not advised).

Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38
  • I explored more on AutoResetEvent, but if you could explain me little more on the above code like how the event will be triggered and handled, it would be helpful, sorry for asking more! – Chethan Sep 29 '14 at 10:20
  • @Chethan This link explains it pretty well http://www.codeproject.com/Articles/27366/Beginner-s-Guide-to-Threading-in-NET-Part-of-n#Mutex – Arun Ghosh Sep 29 '14 at 10:55
  • reset.WaitOne() should go inside the foreach loop or it should be outside the loop – Chethan Sep 30 '14 at 12:57
  • @Chethan My understanding is that we need to start all tasks and then wait for one of the task to complete. So it should be outside. – Arun Ghosh Sep 30 '14 at 13:07
  • which method i can use if i want to wait till threads get completed, in future this requirement might step-in! – Chethan Sep 30 '14 at 13:57
0

Here is a solution based on the Task Parallel Library:

// Create a list of tasks for each string in empList
List<Task> empTaskList = empList.Select(emp => Task.Run(() => ComputeSalary(emp)))
                                .ToList();

// Give me the task that finished first.
var firstFinishedTask = await Task.WhenAny(empTaskList); 

A couple of things to note:

  1. In order to use await inside your method, you will have to declare it as async Task or or async Task<T> where T is the desired return type

  2. Task.Run is your equivalent of new Thread().Start(). The difference is Task.Run will use the ThreadPool (unless you explicitly tell it not to), and the Thread class will construct an entirely new thread.

  3. Notice the use of await. This tells the compiler to yield control back to the caller until Task.WhenAny returns the first task that finished.

You should read more about async-await here

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • can I use async-await in VS2010? answer in [link](http://stackoverflow.com/questions/16557032/how-to-use-async-with-visual-studio-2010-and-net-4-0) says we cant use one in VS2010! – Chethan Sep 30 '14 at 05:41
  • No, unfortunately you cant. You can use it starting VS2012 with .NET 4.0 – Yuval Itzchakov Sep 30 '14 at 05:47