从另一个线程和类更新 C# GUI 中的进度条
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10728192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Updating a progress bar in a C# GUI from another thread and class
提问by Xantham
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.
在我的程序中,我想将非 GUI 函数分离到另一个类,并将与 GUI 相关的东西留在主类中。但是,当工作类中的一个工作方法正在执行其工作时,我在更新进度条时遇到了问题。我知道我将不得不在这里使用多线程,但我不明白如何。我可能只是遗漏了一些简单的东西,但是当我查找有关它的信息时,似乎大多数教程都在谈论细节,但并没有很好地解释大局。我部分了解什么是调用和委托命令,但我并不真正了解它们是如何交互的。
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() { }
单独的工人类: 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.
}
}
}
采纳答案by BTownTKD
.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).
.NET 包括一个名为BackgroundWorker的类,它提供了用于报告事件中后台线程进度的方法。该事件在创建 BackgroundWorker 的线程(通常是 UI 线程)上自动调用。
Subscribe to that "ProgressChanged" event, and update the progress bar in that event handler. The official MSDN Documentation provides some sample code.
订阅该“ProgressChanged”事件,并更新该事件处理程序中的进度条。官方 MSDN 文档提供了一些示例代码。
回答by Chris Pfohl
MethodInvoker mi = new MethodInvoker(() => progressBar.Progress = newProgressValue);
if (progressBar.InvokeRequired)
{
progressBar.Invoke(mi);
}
else
{
mi.Invoke();
}
This code belongs in the lengthy task. See:
此代码属于冗长的任务。看:
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.
Lambda 只是内联声明的函数(或方法)的一个过于花哨的词,而不是作为类上的方法或支持它们的语言中的原始函数。如果您不将其分配给命名变量,则它是“匿名的”。小心,因为它们“捕获”了它们所需的变量,如果您不理解它们,它们的行为可能会有点奇怪。
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.
lambda 的语法非常简单:() => someValue;与public void SomeMethod() { return someValue; }将内容放入括号中以向 lambda 添加参数几乎相同。如果您只有一个参数,请随意跳过括号。
回答by Md Kamruzzaman Sarker
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);
}

