我想使用进度条创建一个基本的多线程应用程序。这意味着当主线程忙于它正在执行的大型进程时,此进度条将在不同的线程上运行。我已经看过很多关于它的教程。但是它们是多线程的东西是执行大型过程的东西。另一种形式的进度条只显示一个简单的进度条,它使用计时器运行并完成。
这是我现在的代码。
对于帖子:
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。我有什么方法可以做到这一点吗?
答案 0 :(得分:3)
而不是ProgressBar
,您应该将长期运行的非UI代码移动到单独的线程中。在WinForms中执行此操作的标准且更简单的方法是使用BackgroundWorker
组件,这可以引发ProgressChanged
事件,您可以在其中更新UI。需要注意的是,{1}}事件是在UI线程上引发的,而不是在工作线程上引发的,因此您甚至不需要使用ProgressChanged
来执行UI操作(例如更新ProgressBar)。 / p>
答案 1 :(得分:2)
您必须使用Control.Invoke
来避免跨线程问题,但我更倾向于使用BackgroundWorker
来解决它,在Form6
上创建_field
并在{{中使用进度条1}}事件有关详细信息,请参阅此page
ProgressChanged
答案 2 :(得分:2)
您可以使用Background worker进行所有处理,而不是使用主线程进行大型处理。
这是一个简单的例子。
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
}
}