0

在表格的顶部,我做了:

progressBar1.Maximum = 100;
progressBar1.Minimum = 1;

然后在开始我所做的操作的按钮单击事件中:

timer2.Enabled = true;
if (this.backgroundWorker1.IsBusy == false)
            {
                this.backgroundWorker1.RunWorkerAsync();
            }

然后在后台workerdowork事件中:

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

DoWork 事件中的所有函数都在复制文件 Processes() 函数使用我所做的一个新类,该类使用 Process 创建/复制文件。

然后我做了新的 DoProgressBar 事件函数:

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

然后 ProgressChanged 事件:

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

然后完成的事件:

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

和 timer1 滴答事件:

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() 事件/函数做第二部分/其他部分 ReportProgress(i)

然后它进入 Progresschanged 事件并执行:progressBar1.Value = e.ProgressPercentage;

结果是当我单击按钮单击开始操作时,我立即看到进度条几乎移动到最后,而不是根据程序的每个功能/进度移动。

你可以在这里看到我的 Form1 的完整代码:

http://codepaste.net/fuk9w5

编辑:

这是我在函数 Processes() 中的 Form1 中使用的类 ProcessRun 的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;

namespace Diagnostic_Tool_Blue_Screen
{
    class ProcessRun
    {


        public void ProcessesRun()
        {

        }

        public static void Processing(string WorkingDirectory, string FileName, string Arguments, bool StandardOutput, string OutputFileName)
        {
            Process proc = new Process();
            proc.EnableRaisingEvents = true;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardOutput = StandardOutput;
            proc.StartInfo.FileName = FileName;
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.WorkingDirectory = WorkingDirectory;
            proc.StartInfo.Arguments = Arguments;
            proc.Start();
            if (StandardOutput == true)
            {
                string output = proc.StandardOutput.ReadToEnd();
                DumpOutput(WorkingDirectory + "\\" + OutputFileName, output);
            }
            proc.WaitForExit();
            proc.Close();
        }

        private static void DumpOutput(string filename, string output)
        {
            StreamWriter w = new StreamWriter(filename);
            w.Write(output);
            w.Close();
        }
    }
}
4

3 回答 3

0

为什么不把它放到你的代码中呢?这就是我移动进度条的“绿色”部分的方式。

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.
于 2013-07-31T05:56:57.773 回答
0

您的后台线程似乎直接与 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);
}

然后,您可以从工作线程调用此方法,进度条应该会正确更新。

于 2013-07-31T02:31:07.697 回答
0

对于那些在试图找到一种通过交叉线程更改进度条值的方法时最终来到这里的人,这就是你的做法:

form.Invoke((Action)delegate { form.function(); });
于 2016-05-03T16:11:32.950 回答