刚开始接触线程,窗口里有2个ListBox控件,listBox1由主线程填充,listBox2由新线程填充,新线程用了2种方法来启动
方法1,用定义类,listBox2里显示正确
namespace jiamei_c
{
    public partial class Form_copyfile : Form
    {
        int p_int_list = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            while (p_int_list <= 1000)
            {
                listBox1.Items.Add("线程1:第" + p_int_list.ToString() + "步   "+DateTime.Now.ToString());
                MyThread obj = new MyThread(p_int_list.ToString(), listBox2);
                Thread t3 = new Thread(obj.ThreadMain);
                t3.Start();
                Application.DoEvents();
                p_int_list++;
            }
        }
    }    public class MyThread
    {
        private string data;
        ListBox p_listbox;
        public MyThread(string data, ListBox mylistbox)
        {
            this.data = data;
            p_listbox = mylistbox;
        }        public void ThreadMain()
        {
            p_listbox.Items.Add("线程2:第" + data + "步    " + DateTime.Now.ToString());
        }
    }
}
方法2,用自定义方法,数字大了之后,在listBox2里显示有问题,比如连续显示2行“第990步”,下一行就显示“第992步”,991步没有了
namespace jiamei_c
{
    public partial class Form_copyfile : Form
    {
        int p_int_list = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            while (p_int_list <= 1000)
            {
                listBox1.Items.Add("线程1:第" + p_int_list.ToString() + "步   "+DateTime.Now.ToString());
                Thread t3 = new Thread(ThreadMain);
                t3.Start();
                Application.DoEvents();
                p_int_list++;
            }
        }        void ThreadMain()
        {
            listBox2.Items.Add("线程2:第" + p_int_list.ToString() + "步    " + DateTime.Now.ToString());
        }
    }
}
请问这是什么原因?以上2种方法哪个好,有区别吗?
另外以上代码中我都没写t3.Abort(),线程在执行完后会自动退出吗,否则上面的代码新建了1000个进程了?
请指教一下,谢谢!

解决方案 »

  1.   

    对于线程来说,没有什么区别
    线程执行完了会自动退出的,并释放占有的资源
    abort是强制性退出,可能线程占用的资源不会释放干净,建议不要用。
      

  2.   

    如果在线程方法中没有写好异常捕获或安全退出代码.
    最好把线程都声明为后台线程:
    Thread s=new Thread();
    s.IsBackground = True;
    后台线成依赖于主线程执行,如果,你的主线程关闭,后台线程也会跟着关闭.
    如果不是后台线程,主程序退出后,线程会继续执行,直到终止,如果出现异常没有正常退出就会一直占用着内存.
      

  3.   

    你的程序两中方法都有问题,即资源没有同步的问题,这是线程中要解决的重要问题,否则使用线程会出现很多数据上的错误.
    但是,在思路上,还是第一种方法比较好,把一个线程方法放在一个类中,使用对象进行处理,这样有许多好处,特别是线程数据复杂的时候,在对象内部的封装会让整个设计简洁明了.但是第二中方法是在主程序对象中的一个方法,他们的实质是一样的,在具体应用的时候看哪种方面就用哪种方法.
    下面是针对你第二种方法出现的问题的解决:
    --------------------------------------
    用自定义方法,数字大了之后,在listBox2里显示有问题,比如连续显示2行“第990步”,下一行就显示“第992步”,991步没有了 
    ---------------------------------------public partial class Form_copyfile : Form 
        { 
            int p_int_list = 0; 
            private void button1_Click(object sender, EventArgs e) 
            { 
                while (p_int_list <= 1000) 
                { 
                    listBox1.Items.Add("线程1:第" + p_int_list.ToString() + "步  "+DateTime.Now.ToString()); 
                    Thread t3 = new Thread(ThreadMain); 
                    t3.IsBackground = True; //申明为后台线程
                    t3.Start(); 
                    //Application.DoEvents(); 
                    Thread.Sleep(0);//个人建议使用释放时间片的方法
                    p_int_list++; 
                } 
            }         void ThreadMain() 
            { 
                lock(listBox2)  //或者使用lock(this)缩的范围越小效率越高,但是lock的效率本身是非常高的,并不用担心.
                {
                  listBox2.Items.Add("线程2:第" + p_int_list.ToString() + "步    " + DateTime.Now.ToString()); 
                }
            } 
        }