如何在我的方法运行的同时加载进度条

我有一个长时间运行的方法,所以我创建了一个进度条来显示我的方法完成的百分比,但我很难弄清楚如何做到这一点,将我的进度条与我的方法同步 => excelHelper.InsertNewRows(); 。


public void ButtonSubmit_Click(object sender, EventArgs e)

{

    if (isProcessRunning)

    {

        MessageBox.Show("A Process is aleady running");

        return;

    }


    Thread backgroundThread = new Thread(

        new ThreadStart(() =>

        {

            for (int n = 0; n < 100; n++)

            {

                isProcessRunning = true;

                Thread.Sleep(50);

                progressBar1.Invoke(

                    new Action(() =>

                    {

                        progressBar1.Value = n;

                        label3.Text = ("Progress: " + n + "%");

                    }

                 ));

            }

            MessageBox.Show("Thread completed!");

            progressBar1.Invoke(

                new Action(() =>

                {

                    progressBar1.Value = 0;

                }

                ));

            isProcessRunning = false;

        }

        ));

    backgroundThread.Start();

    excelHelper.InsertNewRows();

    var folder = TextOutputFile.Text + @"\" +

    DateTime.Now.ToString("yyyy_MM_dd_") + "SA_Analysis_Report.xlsx";

    excelHelper.Save(folder);

    MessageBox.Show("File has been added to file");

}


胡子哥哥
浏览 82回答 3
3回答

子衿沉夜

excelHelper.InsertNewRows();在我看来,你的问题是,工作线程和进度条线程之间没有任何通信。两个线程都在运行,没有任何有关另一个线程及其进度的信息。您可以重写后台线程,因此它能够将百分比作为参数,该参数在您调用线程时显示。例如伪代码:public void progressbarThread(int percentage) {    // Invoke the percentage to your progressbar, then terminate this thread}public void InsertNewRows() {    // Do something...    // 10%    Thread backgroundThread = new Thread(new ThreadStart(() => progressBarThread(10)));    backgroundThread.Start();    // Do something...    // 50%    Thread backgroundThread = new Thread(new ThreadStart(() => progressBarThread(50)));    backgroundThread.Start();    // etc. etc.}

UYOU

肯定有资源可以帮助您解决这个问题,但是我花了大约 2 天的时间来解决这个问题,所以我将在这里帮助您并减轻您的头痛。进度条本身位于主 UI 线程下(就像表单中的任何对象一样),需要由主线程处理。无论你想做什么,都可以通过这样的线程来处理&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;a,&nbsp;b; &nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;txtUsername.Text; &nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;=&nbsp;txtPassword.Password; &nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;Login&nbsp;=&nbsp;new&nbsp;Thread(()&nbsp;=>&nbsp;CompleteLogin(a,&nbsp;b)); &nbsp;&nbsp;&nbsp;&nbsp;InversePbVisibility(); &nbsp;&nbsp;&nbsp;&nbsp;Login.Start();InversePbVisibility() 方法将被您正在执行的使进度条对用户可见的任何操作所替换。附带说明一下,在声明的线程上运行的任何方法都只能传递变量,而不能传递主线程控制下的任何内容。

慕妹3146593

I use this form class: -using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace Yournamespace{&nbsp; &nbsp; public partial class frmProgressBar : Form&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public Action Worker { get; set; }&nbsp; &nbsp; &nbsp; &nbsp; System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();&nbsp; &nbsp; &nbsp; &nbsp; public const long MINIMUM_DISPLAY_TIME = 300;&nbsp; &nbsp; // Minimum time to display the progress bar is 300 milliseconds&nbsp; &nbsp; &nbsp; &nbsp; public frmProgressBar(Action worker)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(worker == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ArgumentNullException();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Worker = worker;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; protected override void OnLoad(EventArgs e)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; base.OnLoad(e);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Task.Factory.StartNew(Worker).ContinueWith(t => { this.Close(); }, TaskScheduler.FromCurrentSynchronizationContext());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; protected override void OnClosed(EventArgs e)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // the code that you want to measure comes here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; watch.Stop();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var elapsedMs = watch.ElapsedMilliseconds;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (elapsedMs < MINIMUM_DISPLAY_TIME) //ensure progress bar is displayed for at least 100 milliseconds, otherwise it just looks like the parent main form glitches.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long lDelay = MINIMUM_DISPLAY_TIME - elapsedMs;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.Sleep((int)lDelay);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}The form design looks like this : -[![enter image description here][1]][1]&nbsp; [1]: https://i.stack.imgur.com/n4XqU.jpgAnd I call it like this: -&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; using (Yournamespace.frmProgressBar frm = new Yournamespace.frmProgressBar(Yourprocess))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; frm.ShowDialog(this);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }Yourprocess is the code that you want to execute that is causing the delay.The main problem with this implementation is Yourprocess cannot return a value or take parameters. I am sure the code can be changed to accomodate this but I did not have time so I use globals to pass in data and to see results(shame on me).This is not my code, although I have modified it, came from a you tube video - Wait Form Dialog.编辑。我忘了说我将表单设置为 100% 不透明度,因此每当我使用它时,进度条似乎都会漂浮在我的 winform 上方。
打开App,查看更多内容
随时随地看视频慕课网APP