C# 如何使用progressBar为程序中的每个进程执行进度?
在表格的顶部,我做了:C# 如何使用progressBar为程序中的每个进程执行进度?,c#,winforms,progress-bar,C#,Winforms,Progress Bar,在表格的顶部,我做了: progressBar1.Maximum = 100; progressBar1.Minimum = 1; 然后在启动我所做操作的按钮单击事件中: timer2.Enabled = true; if (this.backgroundWorker1.IsBusy == false) { this.backgroundWorker1.RunWorkerAsync(); } private st
progressBar1.Maximum = 100;
progressBar1.Minimum = 1;
然后在启动我所做操作的按钮单击事件中:
timer2.Enabled = true;
if (this.backgroundWorker1.IsBusy == false)
{
this.backgroundWorker1.RunWorkerAsync();
}
private static void DoProgressBar(DoWorkEventArgs e, BackgroundWorker worker)
{
for (int i = 1; i <= 90; i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(50);
worker.ReportProgress(i);
}
}
}
然后在backgroundworkerdowork事件中:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (filesContent.Length > 0)
{
for (int i = 0; i < filesContent.Length; i++)
{
File.Copy(filesContent[i], Path.Combine(contentDirectory, Path.GetFileName(filesContent[i])), true);
}
}
DoProgressBar(e, worker);
WindowsUpdate();
CreateDriversList();
GetHostsFile();
Processes();
}
然后,完成的事件:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
this.label1.Text = "Canceled!";
}
else if (!(e.Error == null))
{
this.label1.Text = ("Error: " + e.Error.Message);
}
else
{
this.progressBar1.Value = this.progressBar1.Maximum;
processfinish = true;
}
}
Timer2滴答事件:
private void timer2_Tick(object sender, EventArgs e)
{
timerCount += 1;
TimerCount.Text = TimeSpan.FromSeconds(timerCount).ToString();
TimerCount.Visible = true;
if (processfinish == true)
{
timer2.Enabled = false;
timer1.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count++;
Diagnose.Text = "PROCESS HAS FINISHED" + " " + countBack--;
if (count == 6)
{
Diagnose.Text = "COLLECT INFORMATION";
Diagnose.Enabled = true;
CreateZip.Enabled = true;
ViewLogFile.Enabled = true;
DriverVerifier.Enabled = true;
timer1.Enabled = false;
TimerCount.Visible = false;
}
}
和计时器1滴答事件:
private void timer2_Tick(object sender, EventArgs e)
{
timerCount += 1;
TimerCount.Text = TimeSpan.FromSeconds(timerCount).ToString();
TimerCount.Visible = true;
if (processfinish == true)
{
timer2.Enabled = false;
timer1.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count++;
Diagnose.Text = "PROCESS HAS FINISHED" + " " + countBack--;
if (count == 6)
{
Diagnose.Text = "COLLECT INFORMATION";
Diagnose.Enabled = true;
CreateZip.Enabled = true;
ViewLogFile.Enabled = true;
DriverVerifier.Enabled = true;
timer1.Enabled = false;
TimerCount.Visible = false;
}
}
我知道这是一个很长的代码,但这里的一切都是连接的
我想做的是progressBar将根据DoWork事件中每个函数的进度获得进度
但是,它现在正在做的事情首先是:
DoProgressBar()事件/函数执行第二部分/其他部分报告进度(i)
然后转到Progresschanged事件并执行:progressBar1.Value=e.ProgressPercentage
结果是,当我单击按钮单击开始操作时,我立即看到进度条几乎移动到末尾,而不是根据程序的每个功能/进度移动
你可以在这里看到我完整的Form1代码:
http://codepaste.net/fuk9w5
编辑:
这是我在函数processs()的Form1中使用的ProcessRun类的代码
您的后台线程似乎直接与UI元素(进度条)交互。这是个问题。您的后台线程不能直接与UI元素交互;它必须调用它,以便在UI线程上进行UI更新 例如,您可以在表单中添加如下方法:
// Form method for updating progress bar; callable from worker thread
public void UpdateProgressBar(double progress)
{
// dispatch the update onto the form's thread
Dispatcher.BeginInvoke((Action<double>)((n) =>
{
// do the update in the form's thread
progressBar1.Value = n;
}), progress);
}
//更新进度条的表单方法;可从工作线程调用
public void UpdateProgressBar(双进度)
{
//将更新发送到窗体的线程
Dispatcher.BeginInvoke((操作)((n)=>
{
//在窗体的线程中执行更新
progressBar1.值=n;
}),进度);
}
然后,您可以从工作线程调用此方法,进度条应该会正确更新。为什么不将其放入代码中?这就是我如何移动progressbar的“绿色”部分
progressBar1.Step = pos; //where pos is the number on how much do you want to increase the progress of the progressbar
progressBar1.PerformStep(); //triggers the movement of the progressBar.
对于那些试图通过交叉线程来改变进度条值的人,以下是您的做法:
form.Invoke((Action)delegate { form.function(); });
你可以在这里看到我所有的Form1完整代码:Grant我刚刚再试了一次,现在我标记了timer2.enabled=true;使用//时,它不会被使用,因此它不会启动计时器2滴答事件。我仍然看到progressBar快速向右运行,几乎一直到最后。复制代码时,您对函数processs()使用了什么或做了什么?请对上述代码授予“是”。progressBar向右快速运行,几乎到了终点。我现在试图删除timer2.enabled=true;在button click event diagnose start button click event中,我仍然看到progressBar几乎一直运行到最后。Grant我刚刚更新了我的问题,在那里添加了我调用的ProcessRun类,我在函数Processs()中使用了Form1中的函数Grant我在问题中提供了一个指向完整Form1代码的链接。使用上面的链接,使用完整的Form1代码和我刚刚添加的ProcessRun类,试试看。。。这就是WPF的方式。。。对于WinForms,应为Invoke而不是Dispatcher.BeginInvoke。