如何等待所有线程

时间:2013-07-01 13:40:26

标签: c# multithreading

我有代码,创建5个线程。我需要等待,直到所有线程完成他们的工作,并在返回值之后。我怎么能这样做?

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);
    }
}

当然这不是真正的代码。实际的代码要复杂得多,所以我简化了它。

P.S。仔细看。 我不使用Task,所以我不能使用Wait()或WaitAll()方法。此外,我无法使用Join(),因为Join等待一个线程。如果他们开始等待线程,它已经完成了它们的工作,它将等待无穷大。

6 个答案:

答案 0 :(得分:3)

创建一个如下所示的线程数组并调用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;

答案 1 :(得分:2)

为每个线程创建一个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();
}

获取有关http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

的更多信息

答案 2 :(得分:0)

我认为您可以使用Thread.WaitAll(thread_array),或者在其他情况下您也可以使用Thread.Sleep(100)

Thread.sleep中,100是毫秒数。所以在这种情况下,线程会睡眠100毫秒。

Thread.WaitAll - thread_Array中是您想要等待的线程数组。

答案 3 :(得分:0)

由于此问题实际上是重复的,请参阅this answer,(下面复制的代码,全部归功于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.");
    }
}

除了

另请注意,您的PasswdThread代码不会生成随机数。 <{1}}对象应该在方法之外静态声明,以生成随机数。

此外,您永远不会使用该方法的Random参数。

答案 4 :(得分:0)

我会使用TPL,这是处理这种同步的最新技术。鉴于现实生活中的代码可能更复杂,我会稍微重复一下这个例子:

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;
    });
}

答案 5 :(得分:-1)

    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;