如何使progressbar在C#中的不同线程中运行
本文关键字:线程 运行 progressbar 何使 | 更新日期: 2023-09-27 18:21:24
我想使用进度条创建一个基本的多线程应用程序。这意味着这个进度条将在另一个线程上运行,而主线程正忙于它正在进行的大型进程。我看过很多关于它的教程。但它们是多线程的,是做大进程的。另一种形式的进度条只是显示一个简单的进度条,它使用计时器运行并完成。
这就是我现在拥有的代码。
对于线程:
public void thread()
{
Form6 for6 = new Form6();
for6.Show();
}
TH1 = new Thread(thread);
TH1.Start();
对于进度条(表格6中的代码)
private void timer1_Tick(object sender, EventArgs e)
{
progressBar1.Increment(+1);
if (progressBar1.Value == 99)
{
this.Close();
}
}
private void Form6_Load(object sender, EventArgs e)
{
timer1.Start();
}
我的问题是这里的线程没有运行Form6。有什么办法让我这么做吗?
您可以使用后台工作程序进行所有处理,而不是使用主线程进行大型处理。
这里有一个简单的例子
public partial class Form1 : Form
{
BackgroundWorker bgw = new BackgroundWorker();
public Form1()
{
InitializeComponent();
label1.Text = "";
label2.Text = "";
}
private void button1_Click_1(object sender, EventArgs e)
{
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.WorkerReportsProgress = true;
bgw.RunWorkerAsync();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
int total = 57; //some number (this is your variable to change)!!
for (int i = 0; i <= total; i++) //some number (total)
{
System.Threading.Thread.Sleep(100);
int percents = (i * 100) / total;
bgw.ReportProgress(percents, i);
//2 arguments:
//1. procenteges (from 0 t0 100) - i do a calcumation
//2. some current value!
}
}
void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = String.Format("Progress: {0} %", e.ProgressPercentage);
label2.Text = String.Format("Total items transfered: {0}", e.UserState);
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//do the code when bgv completes its work
}
}
您应该真正将长期运行的非UI代码移动到一个单独的线程中,而不是ProgressBar
。在WinForms中执行此操作的标准且更简单的方法是使用BackgroundWorker
组件,它可以引发ProgressChanged
事件,您可以在其中更新UI。需要注意的是,ProgressChanged
事件是在UI线程上引发的,而不是在工作线程上,因此您甚至不需要使用Invoke()
来执行UI操作(例如更新ProgressBar)。
您必须使用Control.Invoke
来避免跨线程问题,但我更喜欢使用BackgroundWorker
来解决它,在_field
上创建Form6
,并在ProgressChanged
事件中使用进度条。有关更多信息,请参阅本页
public void thread()
{
Form6 for6=null;
Application.OpenForms[0].Control.Invoke(delegate{
for6 = new Form6();
for6.Show();
});
}