Как связать событие изменения прогресса с индикатором выполнения - PullRequest
1 голос
/ 26 сентября 2011

У меня есть приложение Windows Form, которое запускает метод класса от BackgroundWorker.

Я бы хотел добавить окно формы для отображения прогресса.

в методе класса, который у меня естьцикл foreach, поэтому я бы хотел, чтобы каждый цикл отправлял событие формы

с текущим процентом.

вот что я делаю:

public partial class Form1 : Form
    {
        Parsser inst;

        public Form1()
        {
            InitializeComponent();
            inst = new Parsser();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
        }


        private void button2_Click(object sender, EventArgs e)
        {
            if (this.textBox1 != null & this.textBox2 != null)
            {
                if (backgroundWorker1.IsBusy != true)
                {
                    // Start the asynchronous operation.
                    backgroundWorker1.RunWorkerAsync();
                }
            }
        }



        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            inst.init(this.textBox1.Text, this.textBox2.Text);

            inst.ParseTheFile();
            System.Windows.Forms.MessageBox.Show("Parsing finish successfully");

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

    }


}

`

и в классе я делаю это -

public Parsser()
    {
        bgReports = new BackgroundWorker();
        bgReports.WorkerReportsProgress = true;
    }

    public void ParseTheFile()
    {
        Lines = File.ReadAllLines(FilePath);
        this.size = Lines.Length;
        foreach (string line in Lines)
        {

            bgReports.ReportProgress(allreadtchecked/size);

по какой-то причине это не сработает?

Ответы [ 4 ]

1 голос
/ 26 сентября 2011

Передайте лямбда или метод вашему рабочему методу:

в форме:

public void Run()
{
   myParse.DoWork(a => UpdateProgressBar(a.Progress));
}

private void UpdateProgressBar(int progress) { ... }

в парсере:

public void Parse(Action<ProgressArgs> onProgress)
{
   // do your job
   // invoke onProgress whenever needed
   onProgress(current / total * 100);
}
1 голос
/ 26 сентября 2011

Передать ссылку от BackgroundWorker до Parsser и затем использовать этот ссылочный вызов ReportProgrss метод

BackgroundWorker worker;

public Parsser(BackgroundWorker bg)
    {
        worker = bg;
    }

public void ParseTheFile()
{
    Lines = File.ReadAllLines(FilePath);
    this.size = Lines.Length;
    foreach (string line in Lines)
    {
        worker.ReportProgress(allreadtchecked/size);
1 голос
/ 26 сентября 2011

Вы создаете дубликат экземпляра BackgroundWorkder в конструкторе класса Parsser. Попробуйте ниже

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        inst.init(this.textBox1.Text, this.textBox2.Text);
        inst.ParseTheFile(backgroundWorker1);
        System.Windows.Forms.MessageBox.Show("Parsing finish successfully");
    }

В классе Parsser.

    public Parsser()
    {
        //Don't initialize backgroundworker here.
    }

    public ParseTheFile(BackgroundWorker bgWorker)
        {
            bgReports = bgWorker;
           .....
        }
0 голосов
/ 26 сентября 2011

Вам необходимо настроить фонового работника на выполнение работы через DoWorkEventHandler. Кроме того, похоже, что каждая половина вашего частичного класса использует свой собственный BackgroundWorker. Вам нужно использовать ту же ссылку. У вас есть bgreports и backgroundWorker1.

backgroundWorker1.DoWork += MyMethod;


// ......


private void MyMethod(object sender, DoWorkEventArgs e)
{
}

Кроме того, почему вы проверяете свои текстовые поля на ноль? Вы пытаетесь проверить их текстовое содержимое строки на ноль? если это так, я бы использовал String.IsNullOrEmpty.

Я думаю, что лучший вариант здесь был бы для вашего "Parsser" (пожалуйста, исправьте орфографию и определите тип / назначение этого класса для кода Opertional), чтобы определить свои собственные события, на которые подписался бы ваш потребительский класс. Парсер не должен отвечать за асинхронную работу. Потребитель должен иметь возможность запускать что-то синхронно или асинхронно. В любом из этих случаев пользовательские события прогрессии могут быть определены и подписаны (опять же, по желанию).

...