小东西WinForm的等待窗口
一般在做WinForm应用时会遇到较长时间的用户操作等待,此时最好加个等待窗口,给用户一个良好的操作体验.
太懒本来想在网上找一个代码的,但没找到合适的,只能自己动手写一个了,附上代码,也给自己做个备份
包括一个private的内建等待窗口类,及一个public的WaitForm类
WaitForm类提供Show及Close两个方法,代码中等待窗口不为模式窗口
在应用中需要操作长时间运作时可用下面的模式调用:
WaitForm.Show(this);//显示等待窗口
DoSomthing();//主窗口长时间操作
WaitForm.Close();//关闭等待窗口
这段代码主要应用了多线程方式完成,使用一个AutoResetEvent事件信号量来做窗口状态处理,并增保证了等待窗口在异常关闭的情况下能正确的退出显示线程.

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;
using System.Threading;
namespace BMSAP.Windows
{

public delegate void ExecutedInvokeHeandle();
/// <summary>
/// 等待窗口
/// </summary>
public class WaitForm
{
/// <summary>
/// 等待窗口对象
/// </summary>
static FrmWait mWait;
/// <summary>
/// 事件状态通知
/// </summary>
static AutoResetEvent mEvents;
/// <summary>
/// 显示状态
/// </summary>
static bool mShowing = false;
/// <summary>
/// 等待状态
/// </summary>
static bool mWaiting = false;
static WaitForm()
{
//全局等待信号
mEvents = new AutoResetEvent(false);
}
/// <summary>
/// 窗口关闭事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void WaitForm_FormClosed(object sender, FormClosedEventArgs e)
{
if (mWaiting || !(sender is FrmWait))
{
//信号等待中被异常关闭,或主窗口被关闭时自动通知信号复位
mEvents.Set();
return;
}
mShowing = false;
//回收等待窗口
try
{
mWait.Dispose();
}
finally
{
mWait = null;
}
}
/// <summary>
/// 显示等待窗口
/// </summary>
/// <param name="pComponet">调用对象,可为控件或窗口</param>
public static void Show(Control pComponet)
{
//已显示则返回
if (mShowing)
return;
//创建等待窗口
mWait = new FrmWait();
//设置窗口关闭事件
mWait.FormClosed += new FormClosedEventHandler(WaitForm_FormClosed);
//启动显示线程
Thread tmpThread = new Thread(show);
tmpThread.Start(pComponet);
}
/// <summary>
/// 关闭等待窗口
/// </summary>
public static void Close()
{
if (mShowing)
//如果显示中则设置关闭信号
mEvents.Set();
//修改等待状态
mWaiting = false;
}
/// <summary>
/// 显示窗口过程
/// </summary>
/// <param name="pComponet"></param>
static void show(object pComponet)
{
if (pComponet != null &&
pComponet is Control)
{
//设置显示状态
mShowing = true;
//当调用对象为Win控件时
(pComponet as Control).BeginInvoke(new ExecutedInvokeHeandle(delegate()
{
//进行异步调用
if (pComponet != null &&
pComponet is Control)
{
//显示等待窗口
mWait.Show((pComponet as Control).FindForm());
//设置父级窗口关闭事件
(pComponet as Control).FindForm().FormClosed += new FormClosedEventHandler(WaitForm_FormClosed);
//激活父级窗口,
(pComponet as Control).FindForm().Activate();
}
else
{
//如查询不到父级窗口设置顶层显示,此处可用GetDesktop的API来获取桌面窗口,并设置为父级窗口
mWait.TopMost = true;
//显示等待窗口
mWait.Show();
}
}));
//设置等待信号
mWaiting = true;
mEvents.WaitOne();
//等待结束
mWaiting = false;
(pComponet as Control).BeginInvoke(new ExecutedInvokeHeandle(delegate()
{
//关闭窗口
mWait.Close();
}));
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix