zoukankan      html  css  js  c++  java
  • 分享一个线程安全的加载窗体

    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 修改了界面假死和禁止从其他线程访问的问题
  • 相关阅读:
    设置android:supportsRtl=&quot;true&quot;无效问题
    使用 Docker/LXC 迅速启动一个桌面系统
    快速部署Python应用:Nginx+uWSGI配置详解
    链表源代码(C语言实现)
    delete
    Linux与Unix shell编程指南(完整高清版).pdf
    数据挖掘python,java
    shops
    如何用Excel打开CSV文件
    svn迁移到git
  • 原文地址:https://www.cnblogs.com/woodywu/p/3244229.html
Copyright © 2011-2022 走看看