【问题标题】:How to show an animated loading form while executing code in Windows Forms C#如何在 Windows 窗体 C# 中执行代码时显示动画加载窗体
【发布时间】:2015-09-27 17:29:12
【问题描述】:

我想在主窗体中执行一些代码时显示一个动画加载窗体。动画表单仅用于向用户显示操作正在执行,并且我想在操作完成后关闭它。我正在使用的代码是:

    public partial class Form_main_admin : Form
    {
        private Thread loadingThread;
        private string loadingText;

        public Form_main_admin()
        {
            InitializeComponent();
        }

     private void main_tabControl_SelectedIndexChanged(object sender, EventArgs e)
     { 
         switch (main_tabControl.SelectedIndex)
         {
             case 0:
                 // ...
                 break;
             case 1:
                 showLoadingForm("Loading");

                 // Load a datagridview (load data, adjust column widths) in Form_main_admin

                 closeLoadingForm();
                 break;
            }
    }

    private void showLoadingForm(string text)
    {
         loadingText = text;
         loadingThread = new Thread(new ThreadStart(openLoadingForm));
         loadingThread.Start();
    }

    private void openLoadingForm()
    {
         try
         {
             Form_loading loadingForm = new Form_loading(loadingText);
             loadingForm.ShowDialog();
         }
         catch 
         {
             Thread.ResetAbort();
         }
     }

     private void closeLoadingForm()
     {
         try
         {
             loadingThread.Abort();
         }
         catch 
         {
             Thread.ResetAbort();
         }

     }
}

问题是当我在选项卡之间快速切换时出现“线程被中止”异常(参见下面链接中的图片)。

http://postimg.org/image/bvre2bmi5/

如果用户切换标签的速度过快,我不希望用户看到此异常。在阅读了这个论坛上的其他帖子后,我意识到不推荐我的实现。有人可以告诉我如何正确实现此功能吗?

【问题讨论】:

  • 基本原则是只在主线程中更新HMI,并为“后台”任务运行额外的线程。然后,您应该首先在辅助线程中加载 DataGridView 源,在主线程上显示您的动画表单。然后,当数据加载完成后,将此数据分配给 datagidview 并关闭动画表单。
  • 你可以用鼠标光标代替动画来指示有一些工作正在完成。看看这里stackoverflow.com/questions/1568557/…
  • 这是一个非常标准的错误,它有非常令人讨厌的后果,可能会在“加载表单”关闭后很长时间使您的程序崩溃。很难调试,看起来like this。您必须反其道而行之,在 UI 线程上显示加载表单并在工作线程上执行慢速代码。 BackgroundWorker 让它变得简单。
  • 也许可以试试using (Form_loading loadingForm = new Form_loading(loadingText)) { loadingForm.ShowDialog(); //Your data loading code here loadingForm.Close(); } 但我不推荐这个解决方案。最好只使用等待鼠标光标或在标签页中间添加一个进度条。
  • @Graffito 感谢您解释正确的实现原理。 vidriduch,谢谢你的建议。我忘记了我可以使用鼠标来显示加载活动。我将光标改一下,因为实现更简单,功能也一样。

标签: c# forms winforms splash-screen


【解决方案1】:

如果您需要动画进度表,请尝试使用BackgroundWorker 类在附加线程中执行加载:

    public partial class MainForm : Form
    {
        /// <summary>
        /// Some progress form
        /// </summary>
        WaitForm waitForm = new WaitForm();

        /// <summary>
        /// https://msdn.microsoft.com/library/cc221403(v=vs.95).aspx
        /// </summary>
        BackgroundWorker worker = new BackgroundWorker();

        public MainForm()
        {
            InitializeComponent();

            worker.DoWork += (sender, args) => PerformReading();
            worker.RunWorkerCompleted += (sender, args) => ReadingCompleted();
        }

        /// <summary>
        /// This method will be executed in an additional thread
        /// </summary>
        void PerformReading()
        {
            //some long operation here
            Thread.Sleep(5000);
        }

        /// <summary>
        /// This method will be executed in a main thread after BackgroundWorker has finished
        /// </summary>
        void ReadingCompleted()
        {                        
           waitForm.Close();
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            //Run reading in an additional thread
            worker.RunWorkerAsync();
            //Show progress form in a main thread
            waitForm.ShowDialog();
        }
    }

【讨论】:

    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2022-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多