web-dev-qa-db-ja.com

プロセスが終了するのを待っている間にロードコントロールを表示するにはどうすればよいですか?

私はこのサードパーティのコンポーネントを使用して、Windowsフォームで単純な読み込みコントロールを作成することにしました。

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

これは、1回のリクエストで「アクティブ」プロパティをtrueまたはfalseに変更してオンとオフを切り替えると正常に機能します(1回に1回)。問題は、プロセスが提供されるのを待っているときで、プロセスを開始する前にloadingControlをアクティブにしたり、プロセスを終了する必要があると「考える」ときにオフにしたりします。実行すると、画像の読み込みが静的な画像として表示されます。 (アニメーションなし)。

この質問は申し訳ありませんが、C#は初めてです。しかし、スレッドなどを使用する必要があると思います。

だから私の一般的なコードはこれです:

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

ただし、Always the Loadingはアニメーションなしの静的な画像として表示されます。

12
Edgar Alfonso

単に2つのプロパティを設定して終了するスレッドを作成します。 t.Abortはおそらく、何もしません。スレッドがその時点で終了しているからです。さらに悪いことに、UIスレッドでExcelファイルをインポートすると、アニメーションがブロックされ、UI全体がフリーズします。

これはあなたがそれを作る方法です:

備考:もちろん、フォームがレスポンシブである場合は、コントロールを無効/有効にし、フォームが負荷。

1。スレッドの使用

スレッドを明示的に使用する場合は、次のようにします。

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は、終了時にイベントをスローできます。

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

。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);
    }
}
28
György Kőszeg

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;
}
7
Surfin Bird