Зависает progress bar

502
28 ноября 2016, 18:43

Возник вопрос следующего плана: хочу поставить ProgressBar об информирования пользователя о том,что идет проверка файлов (.xlsx). Проверяет достаточное время... И тут, значит, одна проблема возникает, при проверке программа перестает отвечать и, соответственно ProgressBar не заполняется, только после того, как программа отвиснет , то сразу заполняется ProgressBar.

private void button4_Click_1(object sender, EventArgs e)
{
  string StartupPath = Application.StartupPath;
  X509Chain chain = new X509Chain();
  string[] file = Directory.GetFiles(Properties.Settings.Default.ExtractDir, textBox1.Text, SearchOption.AllDirectories); // метод поиска файлов ".xlsx" по массиву 
  foreach (string ex in file)
  {       
      string document = Path.Combine(Properties.Settings.Default.ExtractDir, ex);
      try
      {             
          using (Package package = Package.Open(document)) // Открываем документ
          {
              listBox1.Items.Add("Файл '" + Path.GetFileName(ex) + "':"); //запись файла
              PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package);
              if (!dsm.IsSigned) //проверка документы на наличие подписи
              {
                  listBox1.Items.Add("Документ не подписан.");
              }
              int count = 1;
              foreach (PackageDigitalSignature pds in dsm.Signatures)
              {
                  string s = pds.Signer.GetName();
                  string text = s.Remove(0, s.IndexOf("CN="));
                  listBox1.Items.Add(count++ + "." + " Подпись на сертификате :" + text); //подпись на сертификате
                  if (chain.Build(new X509Certificate2(pds.Signer))) //условие проверки действительности сертификата
                      listBox1.Items.Add("  сертификат действителен");
                  else
                      listBox1.Items.Add("  сертификат недействителен");         
              }
          }
      }
      catch  // обработка исключения
      {
          listBox1.Items.Add("Файл '" + Path.GetFileName(ex) + "':");
          listBox1.Items.Add("- неверный формат ");
      }
  }
}
Answer 1

Вы не привели код, работающий с ProgressBar'ом, но симптомы вашей проблемы ясны.

У вас есть код, интенсивно использующий процессор, и вы вызываете его главном потоке. Но в UI-фреймворках, в отличие от программ командной строки, принята событийная модель: UI посылает события, которые должны быть быстро обработаны программой, и в промежутках между такой обработкой занимается отрисовкой самого UI. В вашем случае обработка нажатия на кнопку происходит очень долго, и всё это время UI таким образом не обновляется! Когда обработка заканчивается, UI «догоняет» состояние, в котором он должен быть, т. к. у него появляется время для этого.

Традиционное решение таких вот проблем — многопоточность. Вы должны переделать код так, чтобы длинная операция только запускалась в другом потоке (это быстро), и ваш код не дожидался её окончания. Когда операция добежит до конца, она может каким—либо образом проинформировать остальную часть приложения о том, что есть результат, вы сможете его показать пользователю (это снова делается в главном по потоке).

Без асинхронности никуда.

Современный метод реализации асинхронности — использование async/await. Обязательно почитайте об этом, с ним ваша проблема решается очень просто.

READ ALSO
Как редактировать таблицу используя JewelryModelView

Как редактировать таблицу используя JewelryModelView

Я изучаю mvcВозникли вопросы связанные с редактированием полей

412
Entity Framework + SQLite

Entity Framework + SQLite

Базы не существует, делаю через Code FirstНужно, чтобы бд и все таблицы создавались автоматически по классам моделей

2274