using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; namespace Eits.Util { public class LoadingPanelHelper { private static Thread thd = null; private static FormLoadingPanel proc = null; private static readonly object syncRoot = new object(); public static void Show(string status = "正在加载应用数据......") { if (proc == null) { Monitor.Enter(syncRoot); if (proc == null) { FormLoadingPanel temp = new FormLoadingPanel(); Interlocked.Exchange(ref proc, temp); } Monitor.Exit(syncRoot); } if ((thd == null || (thd != null && !thd.IsAlive))) { Monitor.Enter(syncRoot); if ((thd == null || (thd != null && !thd.IsAlive))) { Thread temp = new Thread(() => Application.Run(proc)); temp.IsBackground = true; temp.SetApartmentState(ApartmentState.STA); temp.Start(); Interlocked.Exchange(ref thd, temp); } Monitor.Exit(syncRoot); } Monitor.Enter(syncRoot); proc.SetStatusInfo(status); Monitor.Exit(syncRoot); } public static void Close() { if (thd != null && thd.IsAlive && proc != null && !proc.IsDisposed) { Monitor.Enter(syncRoot); if (thd != null && thd.IsAlive && proc != null && !proc.IsDisposed) { proc.CloseForm(); } Monitor.Exit(syncRoot); } } } }
LoadingPanelHelper类是用来展示状态或者关闭状态的,下面是Loading的展示Form,使用了Infragistics的一个控件,大家可以自行删除,仅仅起了个美观的作用.
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; namespace Eits.Util { public partial class FormLoadingPanel : Form { public FormLoadingPanel() { InitializeComponent(); Control.CheckForIllegalCrossThreadCalls = false; } public void SetStatusInfo(string status) { if (this.InvokeRequired) { this.Invoke(new Action<string>(SetStatusInfo), status); } else { this.lblStatus.Text = status; }
if (this.IsHandleCreated && !this.Visible)
{
this.Invoke(new Action(this.Show));
}
} public void CloseForm() { if (this.InvokeRequired) { this.Invoke(new Action(CloseForm)); } else { if (this.IsHandleCreated && !this.IsDisposed) { this.Invoke(new Action(this.Hide)); } } } } }
Designer部分
namespace Eits.Util { partial class FormLoadingPanel { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.ultraActivityIndicatorProgressStatus = new Infragistics.Win.UltraActivityIndicator.UltraActivityIndicator(); this.lblStatus = new Infragistics.Win.Misc.UltraLabel(); this.pnl = new Infragistics.Win.Misc.UltraPanel(); this.pnl.ClientArea.SuspendLayout(); this.pnl.SuspendLayout(); this.SuspendLayout(); // // ultraActivityIndicatorProgressStatus // this.ultraActivityIndicatorProgressStatus.AnimationEnabled = true; this.ultraActivityIndicatorProgressStatus.AnimationSpeed = 35; this.ultraActivityIndicatorProgressStatus.CausesValidation = true; this.ultraActivityIndicatorProgressStatus.Dock = System.Windows.Forms.DockStyle.Bottom; this.ultraActivityIndicatorProgressStatus.Location = new System.Drawing.Point(0, 23); this.ultraActivityIndicatorProgressStatus.Name = "ultraActivityIndicatorProgressStatus"; this.ultraActivityIndicatorProgressStatus.Size = new System.Drawing.Size(410, 23); this.ultraActivityIndicatorProgressStatus.TabIndex = 0; this.ultraActivityIndicatorProgressStatus.TabStop = true; // // lblStatus // this.lblStatus.Dock = System.Windows.Forms.DockStyle.Fill; this.lblStatus.Location = new System.Drawing.Point(0, 0); this.lblStatus.Name = "lblStatus"; this.lblStatus.Size = new System.Drawing.Size(410, 23); this.lblStatus.TabIndex = 1; this.lblStatus.Text = "正在加载应用数据......"; // // pnl // this.pnl.BorderStyle = Infragistics.Win.UIElementBorderStyle.Etched; // // pnl.ClientArea // this.pnl.ClientArea.Controls.Add(this.lblStatus); this.pnl.ClientArea.Controls.Add(this.ultraActivityIndicatorProgressStatus); this.pnl.Dock = System.Windows.Forms.DockStyle.Fill; this.pnl.Location = new System.Drawing.Point(3, 3); this.pnl.Name = "pnl"; this.pnl.Size = new System.Drawing.Size(414, 50); this.pnl.TabIndex = 2; // // FormProgressStatus // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(420, 56); this.Controls.Add(this.pnl); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Name = "FormProgressStatus"; this.Padding = new System.Windows.Forms.Padding(3); this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = " "; this.TopMost = true; this.pnl.ClientArea.ResumeLayout(false); this.pnl.ResumeLayout(false); this.ResumeLayout(false); } #endregion private Infragistics.Win.UltraActivityIndicator.UltraActivityIndicator ultraActivityIndicatorProgressStatus; private Infragistics.Win.Misc.UltraLabel lblStatus; private Infragistics.Win.Misc.UltraPanel pnl; } }
经过本人多次测试,应该是没有问题的,多个线程同时访问也OK,测试机器是 win7 + .net 4.0 ,如有任何问题,欢迎大家跟帖指正,Thanks.
//2013-08-08 修改了界面假死和禁止从其他线程访问的问题