请问各位一个问题 我有一个带参数的方法需要多线程执行,如何等待线程都执行完了再执行主线程的代码呢?如下是我写的代码,但是没法调用events.Set(),如有更好的建议也行
不希望使用线程池,因为我以后考虑提供暂停线程的方法   class Program
    {
        private static AutoResetEvent[] events;
        static void Main(string[] args)
        {
            int threadNum = 10;
            Thread[] thread = new Thread[threadNum];            events = new AutoResetEvent[threadNum];            for (int i = 0; i < threadNum; i++)
            {
                events[i] = new AutoResetEvent(false);                ThreadStart starter = delegate
                                          {
                                              Print("test print:" + i);
                                          };
                thread[i] = new Thread(starter)
                                {
                                    Name = "thread" + i.ToString()
                                };
            }            for (int i = 0; i < threadNum; i++)
            {
                thread[i].Start();
            }            WaitHandle.WaitAll(events);
            Console.Read();
        }        private static void Print(object str)
        {
            Console.WriteLine(Thread.CurrentThread.Name + ": Begin!");
            Console.WriteLine(Thread.CurrentThread.Name + ": Print" + str);
            Console.WriteLine(Thread.CurrentThread.Name + ": End!");            //events[eventNum].Set();
        }
    }

解决方案 »

  1.   

    using System;
    using System.Threading;namespace ConsoleApplication1
    {
        class Program
        {
            private static AutoResetEvent[] events;        static void Main(string[] args)
            {
                int threadNum = 10;
                Thread[] thread = new Thread[threadNum];            events = new AutoResetEvent[threadNum];            for (int i = 0; i < threadNum; i++)
                {
                    var waithandler = new AutoResetEvent(false);
                    events[i] = waithandler;
                    ThreadStart starter = delegate
                    {
                        var param = new Tuple<string, AutoResetEvent>("test print:" + i, waithandler);
                        Print(param);
                    };
                    thread[i] = new Thread(starter)
                    {
                        Name = "thread" + i.ToString()
                    };
                }            for (int i = 0; i < threadNum; i++)
                {
                    thread[i].Start();
                }            WaitHandle.WaitAll(events);
                Console.WriteLine("Completed!");
                Console.Read();        }        private static void Print(object param)
            {
                var p = (Tuple<string, AutoResetEvent>)param;
                Console.WriteLine(Thread.CurrentThread.Name + ": Begin!");
                Console.WriteLine(Thread.CurrentThread.Name + ": Print" + p.Item1);
                Thread.Sleep(300);
                Console.WriteLine(Thread.CurrentThread.Name + ": End!");
                p.Item2.Set();
            }
        }
    }
      

  2.   

    既然是一次性地Set,其实使用ManualResetEvent就足够了。另外,“暂停”线程跟线程池也没有什么直接冲突。不论你使用还是不使用系统线程池,所谓的“暂停”线程都一样地影响系统。只不过是让线程池中少一个可用线程(而.net4.0线程池中默认可以有2000多工作线程+I/O线程)。
      

  3.   

    改了一下,使用ManualResetEvent:using System;
    using System.Collections.Generic;
    using System.Threading;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var waits = new List<EventWaitHandle>();
                for (int i = 0; i < 10; i++)
                {
                    var handler = new ManualResetEvent(false);
                    waits.Add(handler);
                    new Thread(new ParameterizedThreadStart(Print))
                    {
                        Name = "thread" + i.ToString()
                    }.Start(new Tuple<string, EventWaitHandle>("test print:" + i, handler));
                }
                WaitHandle.WaitAll(waits.ToArray());
                Console.WriteLine("Completed!");
                Console.Read();        }        private static void Print(object param)
            {
                var p = (Tuple<string, EventWaitHandle>)param;
                Console.WriteLine(Thread.CurrentThread.Name + ": Begin!");
                Console.WriteLine(Thread.CurrentThread.Name + ": Print" + p.Item1);
                Thread.Sleep(300);
                Console.WriteLine(Thread.CurrentThread.Name + ": End!");
                p.Item2.Set();
            }    }
    }