简体   繁体   English

如何在进程等待完成时显示加载控件?

[英]How can I display a loading control while a process is waiting for be finished?

I decided to use this third-party component to make a simple loading control in my windows form. 我决定使用这个第三方组件在我的Windows窗体中进行简单的加载控制。

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

This works fine when turns on and off changing the property "Active" to true or false in a single request (one per time). 打开和关闭时,这在单个请求中将属性“Active”更改为true或false(每次一个)时工作正常。 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. 问题是当进程等待服务时,我假装在进程启动之前激活loadingControl,当我“认为”该进程必须完成时关闭。 When I do it, the image loading is shown as a static image. 当我这样做时,图像加载显示为静态图像。 (Without animation). (没有动画)。

I'm sorry for this question, I'm new in C#. 对不起这个问题,我是C#的新手。 But I think that I need to use Threads or something similar. 但我认为我需要使用Threads或类似的东西。

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. 但始终加载显示为没有动画的静态图像。

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. t.Abort可能什么都不做,因为那个时候线程已经退出了。 Even worse, you import the excel file on the UI thread, which blocks any animation and freezes the complete UI. 更糟糕的是,您在UI线程上导入excel文件,该文件会阻止任何动画并冻结整个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. Using threads 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. Background worker 2.背景工作者

The BackgroundWorker can throw an event when it is finished: BackgroundWorker可以在完成时抛出一个事件:

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. Using async-await 3.使用async-await

This is the simplest one. 这是最简单的一个。

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);
    }
}

I'd recommend to use async/await (for C# 5.0): 我建议使用async / await(对于C#5.0):

private void button1_Click(object sender, EventArgs e){
    ImportAsync();
}

private async Task ImportAsync(){
    // UI-thread
    showLoading();
    this.loadingCircle1.Visible = true;

    // wait until task will be finished
    await Task.Run(() => {
        // different non-blocking thread for all the hard work, but without UI-stuff
        // import an Excel
    });

    // going back to UI-thread
    this.loadingCircle1.Visible = false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM