Updating a progress bar in a C# GUI from another t

2019-02-07 11:43发布

Possible Duplicate:
Updating a Progress Bar from Another Thread

In my program, I wanted to separate non-GUI functions to another class, and leave things related to the GUI in the main class. However, I am having issues with updating a progress bar while one of the worker methods in the worker class is doing its job. I know that I will have to work with multithreading here, but I do not understand how. I may just be missing simple things, but when I look for information about it, it seems that most tutorials talk about the minutia, but do not explain the big picture very well. I partially understand what invoke and delegate commands are, but I don't really understand how they interact.

Below is stripped down version of what I want to do. How do I modify this to update the progress bar, but keep the window responsive and repainting?

Main form class:

public partial class Form1 : Form
{
    time_waster thing = new time_waster();

    public Form1()
    {
        InitializeComponent();
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 100;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        thing.something_that_takes_a_while();
    }
}

Separate worker class: class time_waster { public time_waster() { }

    public void something_that_takes_a_while()
    {
        int delay = 200;
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(delay);
            //appropriate code to update the progress bar for each iteration of the for loop.
        }
    }
}

3条回答
等我变得足够好
2楼-- · 2019-02-07 12:04
   static main()
    {
     Thread th = new Thread(calling_function);
     th.start();  
   }


    calling_function()
    {
    //do your work;
   MethodInvoker m = new MethodInvoker( ()=> progressbar.Progress=value);
    progressbar.Invoke(m);
   }
查看更多
叼着烟拽天下
3楼-- · 2019-02-07 12:05

.NET Includes a class called the BackgroundWorker, which provides methods for reporting the progress of the background thread in an event. The event is automatically called on the thread which created the BackgroundWorker (typically, the UI thread).

Subscribe to that "ProgressChanged" event, and update the progress bar in that event handler. The official MSDN Documentation provides some sample code.

查看更多
聊天终结者
4楼-- · 2019-02-07 12:17
MethodInvoker mi = new MethodInvoker(() => progressBar.Progress = newProgressValue);
if (progressBar.InvokeRequired)
{
    progressBar.Invoke(mi);
}
else
{
    mi.Invoke();
}

This code belongs in the lengthy task. See:

  1. InvokeRequired
  2. Invoke
  3. Delegates

Lambda is just an over-fancy word for a function (or method) that is declared inline instead of as a method on class or as a raw function in languages that support them. It's "anonymous" if you don't assign it to a named variable. Be careful because they "Capture" the variables needed by them and can behave a bit strangely if you don't understand them.

The syntax for lambdas is pretty easy: () => someValue; is pretty much the same as public void SomeMethod() { return someValue; } put things into the parentheses to add parameters to the lambda. If you only have one parameter, feel free to skip the parentheses.

查看更多
登录 后发表回答