问题:我应该怎么去回收Stack<Thread>中的Thread?(怎么判断线程完成工作了?然后下一步进行回收)。
我的解决方法:添加Thread停止的事件(st.OnThreadStop += new SimpleThread.ThreadStop(st_OnThreadStop);),在SetStop方法中触发这个事件,这样处理不知道是我代码有问题还是怎么回事,不能实现Thread的重用。下面贴代码:线程池类:using System;
using System.Collections.Generic;using System.Text;
using System.Threading;namespace Demo
{
    //线程状态枚举
    enum ThreadStatus { Running,Stop};    class CopyMeterThreadPool
    {
        Stack<Thread> _pool;        //线程池初始化大小
        private int _num;
        public CopyMeterThreadPool(int capability)
        {
            _num = capability;
            _pool = new Stack<Thread>(capability);
        }        //压栈
        public void Push(Thread thread)
        {
            if (thread == null)
                throw new ArgumentNullException("线程池的线程未初始化!");
            lock (_pool)
            {
                //重新包装要处理的Thread
                SimpleThread st = new SimpleThread(thread);                //注册事件
                st.OnThreadStop += new SimpleThread.ThreadStop(st_OnThreadStop);
                
                _pool.Push(thread);
            }
        }        //事件委托的回收线程方法
        void st_OnThreadStop(object sender, ThreadEventArgs e)
        {
            if (e.Status == ThreadStatus.Stop)
            {
                Thread t = (Thread)sender;
                Push(t);
                Console.WriteLine("成功放入线程池!");
            }
        }        //出栈
        public Thread Pop()
        {
            lock (_pool)
            {
                return _pool.Pop();
            }
        }        public int Count
        {
            get { return _pool.Count; }
        }
        
    }    //封装线程的类
    class SimpleThread
    {
        private Thread thread;        public Thread Thread
        {
            get { return thread; }
            set { thread = value; }
        }
        //声明委托和事件
        public delegate void ThreadStop(object sender, ThreadEventArgs e);        public event ThreadStop OnThreadStop;        
        public SimpleThread(Thread t)
        {
            thread = t;
        }        //问题的关键在这里
        public void SetStop()
        {
            if (thread.ThreadState == ThreadState.Running)
            {
                thread.Abort();
                if (OnThreadStop != null)
                {
                    if (thread.ThreadState == ThreadState.Aborted)
                    {
                        //thread.;
                        OnThreadStop(thread, new ThreadEventArgs(ThreadStatus.Stop));
                    }
                }
            }
            
        }    }
    //参数类
    class ThreadEventArgs:EventArgs
    {
        private ThreadStatus status;        internal ThreadStatus Status
        {
            get { return status; }
        }        public ThreadEventArgs(ThreadStatus status)
            : base()
        {
            this.status = status;
        }    }
}

解决方案 »

  1.   


    //主线程方法类using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Data.SqlClient;namespace Demo
    {
        class Program
        {
            static SqlDataReader sdr = null;
            static int num = 3;
            static CopyMeterThreadPool pool = new CopyMeterThreadPool(num);
            //信号量
            static Semaphore sema = new Semaphore(num, num);        static void Main(string[] args)
            {
                //Print();
                try
                {
                    SqlConnection conn = new SqlConnection("server=10.180.84.37;database=test1;uid=sa;pwd=agile");
                    SqlCommand cmd = new SqlCommand("select * from person_info", conn);
                    conn.Open();
                    sdr = cmd.ExecuteReader();                List<Person> list = new List<Person>();
                    //int j = 0;
                    while (sdr != null && sdr.Read())
                    {
                        Person person = new Person();
                        person.Name = sdr["name"].ToString();
                        list.Add(person);
                    }
                    Console.WriteLine("开始:" + DateTime.Now.Millisecond.ToString());
                    string tstr = DateTime.Now.Millisecond.ToString();                //初始化线程池
                    for (int i = 0; i < num; i++)
                    {
                        Thread th = new Thread(new ParameterizedThreadStart(Print));
                        th.Name = "线程池" + i.ToString();                    pool.Push(th);
                    }                for (int k = 0; k < list.Count; k++)
                    {
                        if (pool.Count > 0 && sema.WaitOne())
                        {
                            Thread t = (Thread)pool.Pop();
                            //封装线程对象和信号量
                            Test test = new Test(list[k], t, sema);                        t.Start(test);
                        }
                    }            }
                catch (Exception e)
                {                Console.WriteLine(e.Message);            }
                finally
                {                Console.WriteLine("结束:" + DateTime.Now.Millisecond.ToString());
                    //Console.ReadLine();
                }
                Thread.Sleep(5000);
                Console.WriteLine("结束时间*****************************************" + DateTime.Now.Millisecond.ToString());
                Console.ReadLine();
            }
            static void Print(object obj)
            {
                //sdr.Read();
                Test test = (Test)obj;
                bool flag = false;
                while (!flag)
                {
                    try
                    {                    for (int i = 0; i < 20; i++)
                        {
                            string str = test.P.Name.ToString();
                            str += "AAA";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";
                            str += "q";                        Console.WriteLine("Print" + i.ToString() + str);
                        }                    Console.WriteLine("__________________________");                }
                    catch (Exception es)
                    { }
                    finally
                    {
                        test.Sema.Release();                    SimpleThread s = new SimpleThread(test.Thread);
                        //调用线程停止的方法,来触发线程停止时的事件
                        s.SetStop();                    flag = true;
                    }
                }        }        static void Print2()
            {
                for (int i = 50; i < 100; i++)
                {
                    Console.WriteLine("Print" + i.ToString());
                }
            }        static void Print()
            {
                Thread t = new Thread(new ThreadStart(Print2));
                t.Start();
                Console.WriteLine("线程开始");
                //t.Abort();
                //Console.WriteLine("线程终止");
                if (t.IsAlive)
                {
                    //t.Start();
                    //t.Abort();
                    if (t.ThreadState == ThreadState.Stopped)
                    {
                        Thread th = t;
                        th.Start();
                    }                //Thread.CurrentContext.DoCallBack(new p(new Test().Print2));
                    Console.WriteLine("线程继续开始");
                }
            }
            class Test
            {            public void Print2()
                {
                    for (int i = 50; i < 100; i++)
                    {
                        Console.WriteLine("Print" + i.ToString());
                    }
                }
                private Semaphore sema;            public Semaphore Sema
                {
                    get { return sema; }
                    set { sema = value; }
                }
                private Person p;            internal Person P
                {
                    get { return p; }
                    set { p = value; }
                }
                private Thread thread;            public Thread Thread
                {
                    get { return thread; }
                    set { thread = value; }
                }            public Test(Person per, Thread t, Semaphore se)
                {
                    sema = se;
                    p = per;
                    thread = t;
                }            public Test(Person per)
                {
                    p = per;
                    //sema = se;
                }            public Test()
                {            }        }        class Person
            {
                private string name;            public string Name
                {
                    get { return name; }
                    set { name = value; }
                }
            }
        }
    }
      

  2.   

    Abort和Aborted状态很含糊的
    最好通过位于运算来判断
    用AutoRestEvent和WaitEventHandle来实现比较稳
      

  3.   


    AutoRestEvent这个类是用来处理多个线程等待的类,用set()来告知线程是否还需要等待,请问,这个我怎么来处理线程是否结束?我刚开始就是用这种方法,不行,不知道你能不能再指点一下。谢了。
      

  4.   

    你是故意不用微软提供的ThreadPool类?
      

  5.   

    类抛出ThreadStop事件的时候类还在运行啊...
    使用AutoRestEvent会使线程进入等待状态,直到其它线程Reset了这个参数.
      

  6.   

    身在屋檐下,你居然还敢不低头——唯一的结果就是头破血流。你既然选择了 .NET 框架,你就尊重一下人家的游戏规则好了。人家明明有 ThreadPool 你不用,要自己去回收 Thread,真想得出来呀你。
      

  7.   

    Abort一直是不被推荐使用的
    有很多情况会造成异常,且在finally之前退出执行线程
      

  8.   


    因为项目中其他地方用了ThreadPool,而我这个线程池是要初始化大小的,我初始化了TreadPool的大小,可能会影响到主程序ThreadPool的运行。
      

  9.   

    补充,主程序中用到了ThreadPool。呵呵
      

  10.   

    第一次出现在推荐区。希望有大侠能帮忙。谢谢推荐的xdjm。
      

  11.   


    ms不像sun啊,要是java应该好点。开源。
      

  12.   

    先开两个线程,一个线程用来实现多线程,或者线程池,另一个线程执行主函数,用join方法等待前一个线程完了再执行。
      

  13.   

    老兄哦,你这个线程池有一个原则性的错误:  在 .NET 框架里,Thread 归框架管不归你管,一个 Thread 停止之后,根据人家的游戏规则就得等着 GC 在他高兴的时候回收。可是你却在这个废线程被回收之前(也许已经被回收了)将它 push 进栈,还打算稍后将它 pop 出来。你是要做废品收购站啊?我说的“身在屋檐下,还敢不低头”就这个意思你好像没领会到。  在 .NET 里自制线程池不是不可以,但是有一个条件,就是池里的任何一个线程都不能停,一旦停下来,它就会在不可预测的时间被GC回收了。所以你的设计得改,从根本上改。
      

  14.   


    呵呵,谢谢,我知道线程是GC去回收的,但是没有办法,程序的框架不是我设计搭建的,你说的我的设计得改,能说清楚点吗?错在什么地方。(我其实也知道用MS的东西就是绑着枷锁跳舞,没有办法,经理要求,虽然现在改为其他的实现,就是用SemaPhore来控制线程,其实也没有重用这个概念了。我只是想把我写了一半的代码继续写下去,看能不能实现。)再次谢谢!