namespace Windows多线程
{ public partial class Form1 : Form { public Form1() { InitializeComponent(); }private void button1_Click(object sender, EventArgs e)
{ ThreadStart start = new ThreadStart(DownLoad); Thread thread = new Thread(start);//实例化Thread类 thread.Start();//MessageBox.Show("下载完成");
} private void Mianji(object r) { double result = Math.PI * Convert.ToInt32(r) * Convert.ToInt32(r); this.Invoke(new Action(delegate() { MessageBox.Show(result.ToString()); }));}
private void DownLoad()
{ for (int i = 30000; i < 30010; i++) { try//为了其中有的帖子不存也能正常下载 { using (WebClient client = new WebClient())//客户端连接 { client.DownloadFile(@"" + i + "/", @"e:\movices\" + i + ".html"); //下面是使用匿名委托的简写方式 this.Invoke(new Action(delegate() { this.textBox1.AppendText("第" + i + "个帖子已经下载完成\n"); })); } } catch (Exception ex) { }//这里就是把异常吃掉 } Action action = new Action(Msg);//只是一个委托, this.Invoke(action); } private void Msg()//这是没有返回值,没有参数的方法 { MessageBox.Show("下载完成"); } //计算圆的面积 private void button2_Click(object sender, EventArgs e) { ParameterizedThreadStart start = new ParameterizedThreadStart(Mianji); Thread thread = new Thread(start); thread.Start(5); } //使用线程池下载帖子 private void button3_Click(object sender, EventArgs e) { //这么写其实只是让线程池启动了一个线程,没有利用多线程来操作 WaitCallback wait = new WaitCallback(DownLoadThreadPool); ThreadPool.QueueUserWorkItem(wait); }private void DownLoadThreadPool(object obj)
{ for (int i = 30000; i < 30010; i++) { try { using (WebClient client = new WebClient()) { client.DownloadFile(@"" + i + "/", @"e:\movices\" + i + ".html"); //使用匿名委托的简写方式 this.Invoke(new Action(delegate() { this.textBox1.AppendText("第" + i + "个帖子已经下载完成\n"); })); } } catch (Exception ex) { } } Action action = new Action(Msg); this.Invoke(action); } //线程池多线程下载 private void button4_Click(object sender, EventArgs e) { for (int i = 30000; i < 30020; i++) { WaitCallback wait=new WaitCallback(DownLoadThreadPool2); ThreadPool.QueueUserWorkItem(wait, i); } } private void DownLoadThreadPool2(object obj) { try { using (WebClient client = new WebClient()) { client.DownloadFile(@"" + Convert.ToInt32(obj) + "/", @"e:\movices\" + Convert.ToInt32(obj) + ".html"); //使用匿名委托的简写方式 this.Invoke(new Action(delegate() { this.textBox1.AppendText("第" + Convert.ToInt32(obj) + "个帖子已经下载完成\n"); })); } } catch (Exception ex) { } } } }随堂笔记
1.如何在子线程中的方法运行完毕之后在主线程执行一些操作
1)在事件中的方法运行完成之后,直接使用委托的方式,将要执行的的代码放到主线程去执行,这个其实就是在子线程中向主线程发送了一个委托请求,委托主线程去执行某个方法 2)自己起一个循环,不断判断子线程的执行状态,也就是ThreadState属性的状态,如果值为Stoped表示执行完毕。 2.在子线程不能够直接访问主线程中的对象(如文本框,按钮),必须使用委托的方式,将代码委托给主线程去执行。 3.使用线程池,并不是先放进去的方法先执行,而是线程池根据实际情况自己来决定先执行哪个方法。 4.并不是向线程池放进几个委托,线程池就开启几个线程去执行,而是根据cpu以及内存的使用情况,自己决定开启几个线程,也许你放进去10个委托,而线程池只开启了3个线程来执行。