在等待过程完成时如何显示加载控件? [英] How can I display a loading control while a process is waiting for be finished?

查看:106
本文介绍了在等待过程完成时如何显示加载控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定使用此第三方组件在Windows窗体中进行简单的加载控件.

I decided to use this third-party component to make a simple loading control in my windows form.

http://www.codeproject.com/Articles/14841/How-to-write-a-loading-circle-animation-in-NET

在打开和关闭单个请求(每次一次)中将活动"属性更改为true或false时,此方法很好用.问题是当一个进程正在等待提供服务时,我假装在进程启动之前将loadingControl激活,并在我认为"该进程必须完成时关闭.当我这样做时,图像加载显示为静态图像. (无动画).

This works fine when turns on and off changing the property "Active" to true or false in a single request (one per time). The problem is when a process is waiting to be served, and I pretend to Active the loadingControl before the process starts and turn off when I "think" that the process has to be finished. When I do it, the image loading is shown as a static image. (Without animation).

对于这个问题,我感到很抱歉,我是C#的新手.但是我认为我需要使用线程或类似的东西.

I'm sorry for this question, I'm new in C#. But I think that I need to use Threads or something similar.

所以我的通用代码是这样:

So my general code is this:

using [libraries here]...;
namespace [namespace here]
{
    Public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.loadingCircle1.Visible = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(showLoading));
            this.loadingCircle1.Visible = true;
            t.Start();

            //Import an Excel

            t.Abort();
        }

        public void showLoading()
        {
            loadingCircle1.Active = true;
            loadingCircle1.RotationSpeed = 10;
        }
    }
}

但是,总是将加载显示为没有动画的静态图像.

But Always the Loading shows as a static image without the animation.

推荐答案

您创建一个线程,该线程仅设置两个属性然后结束. t.Abort可能什么也不做,因为到那时线程已经退出了.更糟糕的是,您将Excel文件导入到UI线程中,这会阻止任何动画并冻结整个UI.

You create a thread, which simply sets two properties and then ends. The t.Abort will probably do nothing, since the thread will have been exited by that time. Even worse, you import the excel file on the UI thread, which blocks any animation and freezes the complete UI.

这是您应该这样做的方式:

This is how you should make it:

备注:当然,如果您的表单具有响应能力,则必须禁用/启用控件,并准备好在加载期间关闭表单时会发生什么情况.

Remark: Of course if your form is responsive, you must disable/enable the controls and prepare to the case what happens if your form is being closed during the load.

1.使用线程

如果您确实要显式使用线程,请按照以下步骤操作:

If you really want to explicitly use threads, do it like this:

public partial class Form1 : Form
{
    public Form1()
    {            
        InitializeComponent();
    }

    private Thread workerThread = null;

    private void btnImport_Click(object sender, EventArgs e)
    {
        // start the animation (I used a progress bar, start your circle here)
        progressBar1.Visible = true;
        progressBar1.Style = ProgressBarStyle.Marquee;

        // start the job and the timer, which polls the thread
        btnImport.Enabled = false;
        workerThread = new Thread(LoadExcel);
        workerThread.Start();
        timer1.Interval = 100;
        timer1.Start();
    }

    private void LoadExcel()
    {
        // some work takes 5 sec
        Thread.Sleep(5000);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (workerThread == null)
        {
            timer1.Stop();
            return;
        }

        // still works: exiting
        if (workerThread.IsAlive)
            return;

        // finished
        btnImport.Enabled = true;
        timer1.Stop();
        progressBar1.Visible = false;
        workerThread = null;
    }
}

2.后台工作者

BackgroundWorker完成后可以引发一个事件:

The BackgroundWorker can throw an event when it is finished:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
        backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
    }


    private void btnImport_Click(object sender, EventArgs e)
    {
        // start the animation
        progressBar1.Visible = true;
        progressBar1.Style = ProgressBarStyle.Marquee;

        // start the job
        btnImport.Enabled = false;
        backgroundWorker1.RunWorkerAsync();
    }

    private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        LoadExcel();
    }

    private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        btnImport.Enabled = true;
        progressBar1.Visible = false;
    }

    private void LoadExcel()
    {
        // some work takes 5 sec
        Thread.Sleep(5000);
    }
}

3.使用async-await

这是最简单的一个.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private async void btnImport_Click(object sender, EventArgs e)
    {
        // start the waiting animation
        progressBar1.Visible = true;
        progressBar1.Style = ProgressBarStyle.Marquee;

        // simply start and await the loading task
        btnImport.Enabled = false;
        await Task.Run(() => LoadExcel());

        // re-enable things
        btnImport.Enabled = true;
        progressBar1.Visible = false;
    }

    private void LoadExcel()
    {
        // some work takes 5 sec
        Thread.Sleep(5000);
    }
}

这篇关于在等待过程完成时如何显示加载控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆