刚开始接触线程,窗口里有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,用定义类,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个进程了?
请指教一下,谢谢!
解决方案 »
- 你心目中Web前端做的好的公司有哪些?你想去哪些公司做Web前端?
- TreeView节点的获取
- 一个窗体到另一个窗体数据的传递
- 有谁在企业做发短信的呀?问问是不是一般都在用短信猫?谁可以提供下发短信的程序,谢谢
- C#中如何调用GetPrivateProfileSection (API)
- C# 开发的ActiveX控件,怎么去给它指定版本
- c#如何读取.xls文件内容?
- 欢迎大家讨论一个关于界面显示的问题!!
- ★★(今天是我一个美丽的同学的生日,大家工作累了都来祝福一下~~谢了)为善良的祝福者另开贴给分18:00结
- 初学者问题!大家进来帮看看!
- 小菜又来问各位大哥。
- C#如何判断datagridview1的数据发生了改变?
线程执行完了会自动退出的,并释放占有的资源
abort是强制性退出,可能线程占用的资源不会释放干净,建议不要用。
最好把线程都声明为后台线程:
Thread s=new Thread();
s.IsBackground = True;
后台线成依赖于主线程执行,如果,你的主线程关闭,后台线程也会跟着关闭.
如果不是后台线程,主程序退出后,线程会继续执行,直到终止,如果出现异常没有正常退出就会一直占用着内存.
但是,在思路上,还是第一种方法比较好,把一个线程方法放在一个类中,使用对象进行处理,这样有许多好处,特别是线程数据复杂的时候,在对象内部的封装会让整个设计简洁明了.但是第二中方法是在主程序对象中的一个方法,他们的实质是一样的,在具体应用的时候看哪种方面就用哪种方法.
下面是针对你第二种方法出现的问题的解决:
--------------------------------------
用自定义方法,数字大了之后,在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());
}
}
}