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

三世轮回 提交于 2019-11-27 04:17:05

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. Using threads

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

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. Using 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):

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!