c#簡單的進度條UI滯後解決方法
C#實現進度條方法很多,一般專案中簡單的進度條就可以了,但不管是委託還是多執行緒發現都有進度條UI顯示滯後的問題。一般是讓執行緒Sleep(500),但我發現還是有點不同步,可能是我太菜了,後來找到使用進度條空間的step()方法可以避免進度條進度與提示不同步問題,這裡為了能使進度條控制元件使用方便,寫了個工具類呼叫,這樣簡單方便通用。測試程式碼如下: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { } private void button2_Click(object sender, EventArgs e) { try { ProgreeeBarUtil.ShowProgreeBarFrm(this,0,10000,1); for (int i = 0; i <= 10000; i++) { //object[] objs = new object[] { i, string.Format("當前進度{0}", i) }; //ProgreeeBarUtil.SetProgreessBarValue(objs); ProgreeeBarUtil.SetProgreessBarTip(string.Format("當前進度{0}", i)); } ProgreeeBarUtil.ClosePProgreeBarFrm(); } catch (Exception ex) { } } } public partial class ProgressBarFrm : Form { public ProgressBarFrm() { InitializeComponent(); this.progressBar1.Minimum = 0; this.progressBar1.Maximum = 100; } public ProgressBarFrm(int Minimum, int Maximum,int step) { InitializeComponent(); this.progressBar1.Minimum = Minimum; this.progressBar1.Maximum = Maximum; this.progressBar1.Step = step; } } /// <summary> /// 進度條工具類 /// </summary> public class ProgreeeBarUtil { private static Thread thread; private static Form parentForm; private static ProgressBarFrm progressBarFrm; private delegate void SetValue(object value); #region 設定進度條風格 #endregion public static void ShowProgreeBarFrm(object parentFrm) { parentForm = parentFrm as Form; progressBarFrm = new ProgressBarFrm(); progressBarFrm.StartPosition = FormStartPosition.CenterParent; if (parentForm != null) { progressBarFrm.Show(parentForm); parentForm.Enabled = false; StartThread(); } } public static void ClosePProgreeBarFrm() { progressBarFrm.Close(); parentForm.Enabled = true; } public static void ShowProgreeBarFrm(object parentFrm,int minNum,int maxNum,int step) { parentForm = parentFrm as Form; progressBarFrm = new ProgressBarFrm(minNum, maxNum,step); progressBarFrm.StartPosition = FormStartPosition.CenterParent; if (parentForm != null) { progressBarFrm.Show(parentForm); parentForm.Enabled = false; StartThread(); } } public static void InitProgreeBarParam(object[] objs) { } public static void SetMinValue(int minNumber) { progressBarFrm.progressBar1.Minimum = minNumber; } public static void SetMaxValue(int maxNumber) { progressBarFrm.progressBar1.Minimum = maxNumber; } public static void SetStep(int step) { progressBarFrm.progressBar1.Step = step; } /// <summary> /// 重置進度條 /// </summary> /// <param name="maxNumber"></param> /// <param name="step"></param> /// <param name="value"></param> public static void ResetProgressBar(int maxNumber, int step, int value) { progressBarFrm.progressBar1.Minimum = maxNumber; progressBarFrm.progressBar1.Step = step; progressBarFrm.progressBar1.Value = value; Application.DoEvents(); } public static void StartThread() { thread = new Thread(SetProgreessBarValue); thread.IsBackground = true; thread.Start(); } /// <summary> /// 傳當前進度值 /// </summary> /// <param name="value"></param> public static void SetProgreessBarValue(object value) { if (progressBarFrm.InvokeRequired) { SetValue setvalue = SetProgreessBarValue; progressBarFrm.Invoke(setvalue, value); } else { progressBarFrm.progressBar1.PerformStep(); progressBarFrm.label1.Text = Convert.ToInt32(value).ToString(); Application.DoEvents(); Thread.Sleep(100); } } public static void SetProgreessBarValues(object values) { if (progressBarFrm.InvokeRequired) { SetValue setvalue = SetProgreessBarValue; progressBarFrm.Invoke(setvalue, values); } else { if (values != null) { object[] objs = values as object[]; int value = Convert.ToInt32(objs[0]); string tipStr = objs[1].ToString(); progressBarFrm.progressBar1.Value = value; progressBarFrm.label1.Text = tipStr; Thread.Sleep(100); Application.DoEvents(); } } } /// <summary> /// 傳提示資訊 /// </summary> /// <param name="value"></param> public static void SetProgreessBarTip(object value) { if (progressBarFrm.InvokeRequired) { SetValue setvalue = SetProgreessBarValue; progressBarFrm.Invoke(setvalue, value); } else { if (value != null) { string tipStr = value.ToString(); progressBarFrm.progressBar1.PerformStep(); progressBarFrm.label1.Text = tipStr; Application.DoEvents(); } } } } |