惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
P
Proofpoint News Feed
V
Vulnerabilities – Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
K
Kaspersky official blog
Cyberwarzone
Cyberwarzone
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
S
Securelist
L
Lohrmann on Cybersecurity
Security Latest
Security Latest
T
Threatpost
H
Heimdal Security Blog
W
WeLiveSecurity
A
Arctic Wolf
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
IT之家
IT之家
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
TaoSecurity Blog
TaoSecurity Blog
A
About on SuperTechFans
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Azure Blog
Microsoft Azure Blog
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
量子位
Stack Overflow Blog
Stack Overflow Blog
Know Your Adversary
Know Your Adversary
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
GbyAI
GbyAI
Vercel News
Vercel News
C
Cyber Attacks, Cyber Crime and Cyber Security
Latest news
Latest news
D
Darknet – Hacking Tools, Hacker News & Cyber Security
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security

博客园 - Windie Chai

为SharePoint顶部链接开发自定义数据源 SharePoint 2010 JavaScript技巧两则 Windows Phone Background Agent杂谈 Linq to SharePoint,看上去很美 Windows Phone自定义主题 Windows Phone WebBrowser的技巧 《Visual Studio程序员箴言》笔记 HTML5学习碎片 Windows Phone 7 UI设计和交互规范随笔(2) Windows Phone 7 UI设计和交互规范随笔(1) 使用SharePoint Client OM来查询列表的注意事项(2) 使用SharePoint Client OM来查询列表的注意事项 小心Windows Live Writer插件偷走你的博客密码 WindStyle ExifInfo for Windows Live Writer发布 WF4.0活动模型(1):工作流既活动 泛谈SharePoint 2010无代码工作流 如何在SharePoint 2010项目中引用UserProfiles.dll Windstyle SlugHelper for Windows Live Writer发布 让代码看起来更舒服(2):选择适合的字体
[C#]增强响应性,用加载窗体(Splash)来载入主窗体
Windie Chai · 2010-09-07 · via 博客园 - Windie Chai

2010-09-07 13:13  Windie Chai  阅读(8449)  评论()    收藏  举报

许多软件在启动的时候都会显示一个加载窗口(Splash),譬如微软的Visual Studio、Office以及Adobe的许多软件。这些加载窗口很精美,但“漂亮”并不是它们的主要作用。

设想一下用户双击了一个图标,等了许久都没有看到主窗体,就会感到迷惑:是不是刚才没有点中?于是又双击了一次,这次终于看到主窗体了,但看到了两个,因为启动了两次。

如果加载主窗体需要大量时间,那么在加载主窗体的同时去显示一个加载窗体就可以让用户知道软件已经响应了指令,并且正在进行处理,还可以告诉用户当前处理的进度,从而避免了用户的迷惑和误操作。

恰巧最近我的客户也有这样的抱怨,便研究了一下加载窗体的实现方法,顺便记录在这里以免遗忘。

那么就开始编写一个加载窗体吧。

我创建了一个很简单的窗体,它只包含一个Style=Marquee的ProgressBar(这个进度条会不断滚动),下面是它的代码以及注释:

public partial class Splash : Form 
{ 
    public Splash() 
    { 
        InitializeComponent(); 
    }
    //关闭自身 
    public void KillMe(object o, EventArgs e) 
    { 
        this.Close(); 
    }
    /// <summary> 
    /// 加载并显示主窗体 
    /// </summary> 
    /// <param name="form">主窗体</param> 
    public static void LoadAndRun(Form form) 
    { 
        //订阅主窗体的句柄创建事件 
        form.HandleCreated += delegate 
        { 
            //启动新线程来显示Splash窗体 
            new Thread(new ThreadStart(delegate 
            { 
                Splash splash = new Splash(); 
                //订阅主窗体的Shown事件 
                form.Shown += delegate 
                { 
                    //通知Splash窗体关闭自身 
                    splash.Invoke(new EventHandler(splash.KillMe)); 
                    splash.Dispose(); 
                }; 
                //显示Splash窗体 
                Application.Run(splash);
            })).Start(); 
        }; 
        //显示主窗体 
        Application.Run(form); 
    }

代码很好理解,Splash类只包含两个方法:一个普通的事件处理程序KillMe和一个静态方法LoadAndRun。

LoadAndRun方法用于加载并显示主窗体。在加载主窗体的同时,Splash窗体也会一直显示,直到主窗体加载完毕可以完全显示为止。

使用此加载窗体的方法也很简单,只需要把Program.cs中Main方法里的

Application.Run(new Form1());

修改为

Splash.LoadAndRun(new Form1());

即可。

如果想要看到效果,可以在Form1的OnLoad事件中让主线程睡一会儿觉,譬如:

protected override void OnLoad(EventArgs e) 
{ 
    System.Threading.Thread.Sleep(5000); 
    base.OnLoad(e); 
}
 

为什么要在新线程中显示加载窗体呢?因为忙碌的主窗体已经占有了主线程,如果把加载窗体也安排到主线程的话,它不仅很容易变成“失去响应”的状态,而且有可能连自身都无法顺利加载完,更别说不断滚动的进度条了。

另外,这种方法还有一个缺点,如果主窗体加载缓慢是因为在构造函数中执行了大量操作的话,那么这种方法就起不到作用了。

不过话说回来,在窗体的构造函数中执行影响性能的操作本来就是不被推荐的做法,应当尽量避免。