<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>多线程 on 冯威的博客</title><link>https://fwhyy.com/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/</link><description>Recent content in 多线程 on 冯威的博客</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sun, 20 Dec 2009 00:00:00 +0800</lastBuildDate><atom:link href="https://fwhyy.com/tags/%E5%A4%9A%E7%BA%BF%E7%A8%8B/atom.xml" rel="self" type="application/rss+xml"/><item><title>关于多线程的一个例子（UI实时显示）</title><link>https://fwhyy.com/2009/12/an-example-in-respect-to-multithreading/</link><pubDate>Sun, 20 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/an-example-in-respect-to-multithreading/</guid><description>&lt;p&gt;在开发Window应用程序的时候，经常需要在界面上显示出已经执行到什么步骤了，拿一个简单例子来说，创建一个Winform程序，在窗体上访一个Button和一个Label，点击Button时做100次循环，在Label上实时显示当前循环的次数。一种简单的做法就是使用Application.DoEvents，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 label1.Text = i + &amp;#34;/100&amp;#34;;
 Application.DoEvents();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码如果将Application.DoEvents();去掉当点击Button时，程序会卡住，直到这个循环执行完成，当这个循环足够大时是不能忍受的。不过小数据量用Application.DoEvents()还行，数据量大了使用Application.DoEvents()就会带来性能的问题。所以Application.DoEvents()要慎用，在大数据量的时候可以使用多线程解决。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 Thread thread = new Thread(new ThreadStart(DoWork));
 thread.Start();
}
private void DoWork()
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 label1.Text = i + &amp;#34;/100&amp;#34;;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;嗯？出现异常了是吧，没错上面的代码运行后后会出现“线程间操作无效: 从不是创建控件“label1”的线程访问它。”的异常。关于什么原因造成的，大家可以google一下。不过上面代码在vs03中貌似可以正常运行。将代码改成下面这样就可以正常运行了：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 Thread thread = new Thread(new ThreadStart(DoWork));
 thread.Start();
}
private void DoWork()
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 this.Invoke(new Action&amp;lt;string&amp;gt;(this.ChangeLabel),i.ToString());
 }
}
private void ChangeLabel(string i)
{
 label1.Text = i + &amp;#34;/100&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果嫌多写一个ChangeLabel方法费事，可以写成匿名方法的形式，如下：&lt;/p&gt;</description></item></channel></rss>