更新从另一个线程和类[重复]在C#GUI的进度条(Updating a progress bar i

2019-06-24 18:16发布

可能重复:
从另一个线程更新进度条

在我的计划,我想非GUI功能分离到另一个类,并留在主类GUI相关的东西。 但是,我有更新进度条,而在工人阶级中的工人的方法之一是做了工作的问题。 我知道,我将与多线程在这里工作,但我不明白怎么。 我可能只是缺少简单的事情,但是当我寻找有关它的信息,似乎大多数教程谈细节,但不解释大局很好。 我部分明白调用和委托命令,但我真的不明白他们是如何相互作用的。

下面是剥离下来的是我想要做的版本。 如何修改它来更新进度条,但保留窗口响应和重新粉刷?

主窗体类:

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

单独的工作类:类time_waster {公共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.
        }
    }
}

Answer 1:

.NET包含了一个叫做类BackgroundWorker的 ,它提供了报告后台线程的事件进展的方法。 该事件被自动调用这创造BackgroundWorker的(典型地,UI线程)的线程上。

订阅到“ProgressChanged”事件,并更新该事件处理程序的进度条。 官方的MSDN文档提供了一些示例代码。



Answer 2:

MethodInvoker mi = new MethodInvoker(() => progressBar.Progress = newProgressValue);
if (progressBar.InvokeRequired)
{
    progressBar.Invoke(mi);
}
else
{
    mi.Invoke();
}

此代码属于在冗长的任务。 看到:

  1. InvokeRequired
  2. 调用
  3. 代表

LAMBDA仅仅是一个函数(或方法)的过度花哨的词即宣告直列而不是作为类中的方法或在支持他们语言的原始功能。 这是“匿名”如果你不把它分配给一个指定的变量。 要小心,因为他们“捕捉”他们需要的变量,并且可以表现得有点怪异,如果你不理解他们。

为lambda表达式语法是很容易的: () => someValue; 几乎是一样的public void SomeMethod() { return someValue; } public void SomeMethod() { return someValue; }把东西放进括号将参数添加到拉姆达。 如果你只有一个参数,随时跳过括号。



Answer 3:

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


文章来源: Updating a progress bar in a C# GUI from another thread and class [duplicate]