0

我有创建 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);
    }
}

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

PS仔细看。我不使用任务,所以我不能使用方法 Wait() 或 WaitAll()。我也不能使用 Join(),因为 Join 等待一个线程。如果他们启动已经完成工作的等待线程,则将无限等待。

4

6 回答 6

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;
于 2013-07-01T13:47:20.800 回答
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的更多信息

于 2013-07-01T13:43:55.730 回答
0

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;
    });
}
于 2013-07-01T14:09:33.337 回答
0

由于这个问题实际上是重复的,请参阅这个答案,(下面复制的代码,全部归功于 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代码不会产生随机数。该Random对象应在您的方法之外静态声明,以生成随机数。

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

于 2013-07-01T14:00:39.893 回答
0

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

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

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

于 2013-07-01T13:53:00.480 回答
-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;
于 2013-07-01T13:58:45.323 回答