C#: ProgressBar или волшебная информирующая полоска

Сегодня речь пойдет об использовании в своих программах элемента ProgressBar. Для тех кто в танке — это инфомрер, как правило, отображающий процесс выполнения какого-либо долгого действия. По сути будет рассмотрено два вопроса: «как изменить значение элемента формы из потока» и «как работать с элементом прогресс бар»…
Как всегда начнем с пустого ВинФорм проекта, и добавления на него необходимых элементов: Label, Button, ProgressBar. Не будем заморачиваться по смене стандартных надписей и имен объектов — приступим к решительным действиям.
Данный материал был взят с сайта foolsoft.ru
Так как нам нужно какое-либо трудоемкое действие, то остановимся на умножении большого количества случайных чисел. Нажмем на нашу кнопку два раза и в событии клика по кнопке сгенерируем числа:

int Count = 10000;
Random Rnd = new Random();

int[] Mas_1 = new int[Count];
int[] Mas_2 = new int[Count];

for (int i = 0; i < Count; ++i)
{
   Mas_1[i] = Rnd.Next();
   Mas_2[i] = Rnd.Next();
}

В результате имеем десять тысяч случайных чисел. Далее зададим параметры нашего прогресс бара. Так как Мы будем умножать 10000 чисел, то максимальное значение прогресс бара (когда полоска полностью закрашена) очевидно должно быть равно 10000, а текущее значение поставим в ноль.

progressBar1.Maximum = Count;
progressBar1.Value = 0; 

А далее собственно суть вопроса. Для того что бы приложение продолжало работать без зависания формы в процессе долгой обработки, эту самую обработку стоит выполнять в отдельном потоке. А для того чтобы получить доступ к элементам формы из потока, нужно воспользоваться конструкцией this.Invoke(new ThreadStart(delegate{ }));. Имеем:

Thread t = new Thread(new ThreadStart(delegate{
  for (int i = 0; i < Count; ++i)
  {
    this.Invoke(new ThreadStart(delegate
    {
      label1.Text = Mas_1[i].ToString() + " * " +
                    Mas_2[i].ToString() + " = " +
                    (Mas_1[i] * Mas_2[i]).ToString();
      progressBar1.Value++;
    }));
  }
}));

Данный код создает новый процесс с явным указанием кода, который будет выполняться - пройтись по всем числам, показать в элементе label1 какие два числа мы умножаем и каков результат умножения, увеличивать значение элемента progressBar1 на один каждую итерацию цикла.

Полностью код выглядит так:

private void button1_Click(object sender, EventArgs e)
{
  int Count = 10000;
  Random Rnd = new Random();

  int[] Mas_1 = new int[Count];
  int[] Mas_2 = new int[Count];

  for (int i = 0; i < Count; ++i)
  {
   Mas_1[i] = Rnd.Next();
   Mas_2[i] = Rnd.Next();
  }
  
  progressBar1.Maximum = Count;
  progressBar1.Value = 0; 
  
  Thread t = new Thread(new ThreadStart(delegate{
  for (int i = 0; i < Count; ++i)
  {
    this.Invoke(new ThreadStart(delegate
    {
      label1.Text = Mas_1[i].ToString() + " * " +
                    Mas_2[i].ToString() + " = " +
                    (Mas_1[i] * Mas_2[i]).ToString();
      progressBar1.Value++;
    }));
  }
  }));
  t.Start();
}
Запись опубликована в рубрике C# с метками , , , , . Добавьте в закладки постоянную ссылку.