2016/08/28

C#.Net 透過BackgroundWorker更新UI

要用BackgroundWorker不斷更新UI要記得Sleep以免線程卡住,導致UI卡死

UI:
namespace Test
{
 partial class Form1
 {
  /// <summary>
  /// 設計工具所需的變數。
  /// </summary>
  private System.ComponentModel.IContainer components = null;

  /// <summary>
  /// 清除任何使用中的資源。
  /// </summary>
  /// <param name="disposing">如果應該處置 Managed 資源則為 true,否則為 false。</param>
  protected override void Dispose(bool disposing)
  {
   if (disposing && (components != null))
   {
    components.Dispose();
   }
   base.Dispose(disposing);
  }

  #region Windows Form 設計工具產生的程式碼

  /// <summary>
  /// 此為設計工具支援所需的方法 - 請勿使用程式碼編輯器修改
  /// 這個方法的內容。
  /// </summary>
  private void InitializeComponent()
  {
   this.button1 = new System.Windows.Forms.Button();
   this.label1 = new System.Windows.Forms.Label();
   this.SuspendLayout();
   // 
   // button1
   // 
   this.button1.Location = new System.Drawing.Point(12, 12);
   this.button1.Name = "button1";
   this.button1.Size = new System.Drawing.Size(75, 23);
   this.button1.TabIndex = 0;
   this.button1.Text = "button1";
   this.button1.UseVisualStyleBackColor = true;
   this.button1.Click += new System.EventHandler(this.button1_Click);
   // 
   // label1
   // 
   this.label1.AutoSize = true;
   this.label1.Location = new System.Drawing.Point(22, 54);
   this.label1.Name = "label1";
   this.label1.Size = new System.Drawing.Size(33, 12);
   this.label1.TabIndex = 1;
   this.label1.Text = "label1";
   // 
   // Form1
   // 
   this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
   this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
   this.ClientSize = new System.Drawing.Size(284, 261);
   this.Controls.Add(this.label1);
   this.Controls.Add(this.button1);
   this.Name = "Form1";
   this.Text = "Form1";
   this.ResumeLayout(false);
   this.PerformLayout();

  }

  #endregion

  private System.Windows.Forms.Button button1;
  private System.Windows.Forms.Label label1;
 }
}





Code:
using log4net;
using System;
using System.Reflection;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;

namespace Test
{
 public partial class Form1 : Form
 {
  /// <summary>
  /// Logger
  /// </summary>
  private static readonly ILog LOG = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.Name);

  /// <summary>
  /// Update UI worker 
  /// </summary>
  private BackgroundWorker workerUI = new BackgroundWorker();

  public Form1()
  {
   InitializeComponent();
   //初始化Log4Net
   log4net.Config.XmlConfigurator.Configure();

   workerUI.WorkerSupportsCancellation = true;
   workerUI.WorkerReportsProgress = true;

   workerUI.DoWork += (s, e) =>
   {
    if (workerUI.CancellationPending)
    {
     e.Cancel = true;
     return;
    }
    else
    {
     while (!workerUI.CancellationPending)
     {
      workerUI.ReportProgress(0, DateTime.Now.ToString());
      Thread.Sleep(1000);
     }
    }
   };

   workerUI.ProgressChanged += (s, e) =>
   {
    label1.Text = e.UserState.ToString();
   };

  }

  private void button1_Click(object sender, EventArgs e)
  {
   if (workerUI.IsBusy)
   {
    workerUI.CancelAsync();
   }
   else
   {
    workerUI.RunWorkerAsync();
   }
  }

 }
}


執行結果: