简体   繁体   中英

How wait all thread

I have code, that create 5 threads. I need wait, until all threads finished their work, and after return value. How can I do this?

public static int num=-1;

public int GetValue()
{
    Thread t=null;
    for (int i = 0; i <=5; i++)
    {
        t = new Thread(() => PasswdThread(i));
        t.Start();  
    }

    //how wait all thread, and than return value?   
    return num;
}

public void PasswdThread(int i)
{
    Thread.Sleep(1000);
    Random r=new Random();
    int n=r.Next(10);
    if (n==5)
    {
        num=r.Next(1000);
    }
}

Of course this is not a real code. The actual code is much more complicated, so I simplified it.

PS Look carefully. I am not use Task, so I can't use method Wait() or WaitAll() . Also I can't use Join(), because Join wait one thread. If they start wait thread, which already finished they work, the will wait infinity.

Make an array of thread like below and call WaitAll function

List<Thread> threads = new List<Thread>();
Thread thread = null;
 for (int i = 0; i <=5; i++)
 {
     t = new Thread(() => PasswdThread(i));
     t.Start();
     threads.add(t);
 }
Thread.WaitAll(thread);
 //how wait all thread, and than return value?  
 return num;

create a ManualResetEvent handle for each your thread, and then call WaitHandle.WaitAll(handles) in your main thread.

static WaitHandle[] handles = new WaitHandle[5];

`

public void PasswdThread(int i)
{
handles[i] = new ManualResetEvent(false);

 Thread.Sleep(1000);
 Random r=new Random();
 int n=r.Next(10);
 if (n==5)
 {
     num=r.Next(1000);
 }
 handles[i].Set();
}

Get more information on http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

I think you can use Thread.WaitAll(thread_array) or in other case you can also use Thread.Sleep(100)

In Thread.sleep , 100 is number of milliseconds. So in this case thread would sleep for 100 milliseconds.

And in Thread.WaitAll - thread_Array is array of threads that you wanna wait.

As this question is effectively a duplicate, please see this answer , (code copied below, all credit to Reed Copsey.

class Program
{
    static void Main(string[] args)
    {
        int numThreads = 10;
        ManualResetEvent resetEvent = new ManualResetEvent(false);
        int toProcess = numThreads;

        // Start workers.
        for (int i = 0; i < numThreads; i++)
        {
            new Thread(delegate()
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                // If we're the last thread, signal
                if (Interlocked.Decrement(ref toProcess) == 0)
                    resetEvent.Set();
            }).Start();
        }

        // Wait for workers.
        resetEvent.WaitOne();
        Console.WriteLine("Finished.");
    }
}

Aside

Also note that your PasswdThread code will not produce random numbers. The Random object should be declared statically, outside of your method, to produce random numbers.

Additionally you never use the int i parameter of that method.

I would use TPL for this, imo it's the most up to date technique for handling this sort of synchronization. Given the real life code is probably more complex, I'll rework the example slightly:

public int GetValue()
{
    List<Task<int>> tasks = new List<Task<int>>();
    for (int i = 0; i <=5; i++)
    {
        tasks.Add(PasswdThread(i));
    }

    Task.WaitAll(tasks);

    // You can now query all the tasks:
    foreach (int result in tasks.Select(t => t.Result))
    { 
        if (result == 100) // Do something to pick the desired result...
        {
            return result;
        }
    }

    return -1;
}

public Task<int> PasswdThread(int i)
{
    return Task.Factory.StartNew(() => {
        Thread.Sleep(1000);
        Random r=new Random();
        int n=r.Next(10);
        if (n==5)
        {
            return r.Next(1000);
        }
        return 0;
    });
}
    Thread t=null;
List<Thread> lst = new List<Thread();
    for (int i = 0; i <=5; i++)
    {
         t = new Thread(() => PasswdThread(i));
         lst.Add(t);
         t.Start();  
    }

    //how wait all thread, and than return value?   
foreach(var item in lst)
{
    while(item.IsAlive)
    {
         Thread.Sleep(5);
    }
}
    return num;

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