简体   繁体   English

如何等待所有线程

[英]How wait all thread

I have code, that create 5 threads. 我有创建5个线程的代码。 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. PS仔细看。 I am not use Task, so I can't use method Wait() or WaitAll() . 我没有使用Task,所以无法使用Wait()或WaitAll()方法 Also I can't use Join(), because Join wait one thread. 我也不能使用Join(),因为Join等待一个线程。 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 制作如下所示的线程数组并调用WaitAll函数

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. 为每个线程创建一个ManualResetEvent句柄,然后在主线程中调用WaitHandle.WaitAll(handles)

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 http://msdn.microsoft.com/zh-cn/library/z6w25xa6.aspx上获取更多信息

I think you can use Thread.WaitAll(thread_array) or in other case you can also use Thread.Sleep(100) 我认为您可以使用Thread.WaitAll(thread_array)或在其他情况下也可以使用Thread.Sleep(100)

In Thread.sleep , 100 is number of milliseconds. Thread.sleep ,100是毫秒数。 So in this case thread would sleep for 100 milliseconds. 因此,在这种情况下,线程将休眠100毫秒。

And in Thread.WaitAll - thread_Array is array of threads that you wanna wait. Thread.WaitAll thread_Array是您要等待的线程数组。

As this question is effectively a duplicate, please see this answer , (code copied below, all credit to Reed Copsey. 由于此问题实际上是重复的,请参阅此答案 ,(下面复制的代码,全部归功于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. 另请注意,您的PasswdThread代码不会产生随机数。 The Random object should be declared statically, outside of your method, to produce random numbers. 应该在方法之外静态声明Random对象,以产生随机数。

Additionally you never use the int i parameter of that method. 另外,您永远不要使用该方法的int i参数。

I would use TPL for this, imo it's the most up to date technique for handling this sort of synchronization. 我将为此使用TPL,imo是处理此类同步的最新技术。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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