0. 在主程序執行一些長時間的耗時操作時候,(比如很多次的循環for(,,), 或者Thread.Sleep(xxx)), UI會沒有反應。(因爲窗口處理事件是按照消息隊列中的順序來的,沒有處理到的就會帶在隊列裏面,其中可能包括界面重繪即響應事件)。
1. 需要提高界面響應,可以使用新的線程來做一些耗時的操作,同時界面保持響應。
2. 耗時操作完成後,使用Control.Invoke/BeginInvoke來更新界面,有同步和異步兩個方式,InvokeRequired是用來判斷是否需要線程切換(Invoke實際上是把代碼切換到主線程,也就是界面線程上面去執行)
3.搞清楚代碼到底是在哪個線程上面執行。在new Thread()裏面的代碼都是在另外的線程上執行
1.Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace UpdateUITest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string mnem = this.textBox1.Text.Trim();
//string price = GetPriceUsingNewThread(mnem);
GetPriceUsingNewThread(mnem);
}
private void GetPriceUsingNewThread(string mnem)
{
string price = ServiceProvider.GetPrice2(mnem);
this.textBox2.Text = price;
}
private void GetPriceUsingNewThread2(string mnem)
{
string price = string.Empty;
new Thread(()=>
{
price = ServiceProvider.GetPrice(mnem);
if (this.InvokeRequired)
{
this.Invoke(new Action(() =>
{
this.textBox2.Text = price;
}));
}
else
{
this.textBox2.Text = price;
}
}).Start();
}
private void GetPriceUsingNewThreadInLamda(string mnem)
{
string price = string.Empty;
bool hasGotValue = false;
new Thread(()=>
{
price = ServiceProvider.GetPrice(mnem);
hasGotValue = true;
}).Start();
while (!hasGotValue)
{
Application.DoEvents();
}
this.textBox2.Text = price;
}
}
}
2. ServiceProvider.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace UpdateUITest
{
class ServiceProvider
{
public static string GetPrice(string mnem)
{
string resultPrice;
if (mnem.ToUpper() == "IBM")
{
resultPrice = "10.00";
}
else
{
resultPrice = "20.00";
}
System.Threading.Thread.Sleep(9000);
return resultPrice;
}
public static string GetPrice2(string mnem)
{
string resultPrice;
if (mnem.ToUpper() == "IBM")
{
resultPrice = "10.00";
}
else
{
resultPrice = "20.00";
}
//If you are doing something which would last a long time
//,please give main thread(UI thread) a chance to update itself every other few miliseconds.
for (int i = 0; i < 5000; i++)
{
Application.DoEvents();
System.Threading.Thread.Sleep(2);
}
return resultPrice;
}
}
}