2013-05-17 2 views
3

Пункт попытки 2. Попытка быть настолько ясной, насколько это возможно, потому что я выполнял эту задачу намного дольше, чем следовало бы и добился небольшого прогресса.Выполнение строки прогресса в C#

Мне нужно сделать индикатор выполнения для приложения. Прямо сейчас все происходит в одном потоке пользовательского интерфейса, все обрабатывается и еще много чего, поэтому, когда я выполняю длительный процесс после нажатия кнопки, программа зависает примерно 40 секунд, затем возобновляется с выходом (я не могу изменить это часть, заявление было дано мне). И я также должен сделать кнопку отмены, поэтому, если она попадает во время промежуточного процесса, после этого процесса выполняется проверка флажка Отмена, и если он включен, вырываются из всех методов и возвращаются в исходное положение ,

Что мне нужно сделать, это сделать индикатор прогресса для этого процесса. Два из них, один для промежуточного процесса и один для общего. Промежуточное - это небольшое действие, такое как вызов БД, выход промежуточного процесса (для циклов foreach и foreach).

Я попытался поместить бары в том же окне пользовательского интерфейса и обновить их в том же потоке, что и я, (найдите основные моменты, запустите там бары прогресса и увеличите их на основе моего суждения и петель). Это просто загрузило пользовательский интерфейс еще больше, но он работал (изменчивый ход).

Затем я попытался использовать фона рабочего. То же самое, положить бары в пользовательский интерфейс и запустить их через фоновый рабочий. Проблема с этим, хотя рабочий BG работает, обновление должно произойти в окне пользовательского интерфейса, которое занято обработкой жадного запроса, поэтому оно не обновляется, когда я этого хочу.

Я попытался использовать многопоточность в ядре (без работника BG) и создать новую форму в новом потоке, который будет отражать прогресс, но я был предупрежден о том, чтобы не делать этого (одновременно выполнял 2 потока пользовательского интерфейса) и У меня были проблемы, связанные с ценностями. Не говоря уже о том, что при использовании метода потоковой обработки невозможно получить точное представление о прогрессе, не перегружая центральный процессор (запустите другой поток (true) и сделайте обновление, когда вы вызываете метод updateMethod с некоторой точки в процесс)

Есть ли у меня какие-либо другие варианты? Поскольку наименее негативный аспект является первым, когда я обновляю индикатор выполнения, когда я соглашаюсь с программой.

+0

Почему ваш пользовательский интерфейс занят, когда вы выполняете работу в BackgroundWorker? Вся * точка * BGW такова, что UI * не делает ничего. Поток пользовательского интерфейса должен запускать BGW, а затем просто делать, пока BGW отключается, чтобы сделать это самостоятельно. Используйте соответствующие завершенные и обновленные события для обновления пользовательского интерфейса с прогрессом и результатами фоновой работы. – Servy

+0

@Serve Я использую BGW, чтобы сделать индикатор выполнения, а не пользовательский интерфейс. Основной поток, который имеет пользовательский интерфейс, обрабатывает эту длинную 40-секундную задачу. Включение всего в BGW означало бы переписывание половины всей программы. Как я упоминал в OP, мне это было представлено. – Alexey

+1

У меня была эта идея сделать Apllication.DoEvents(), но она была нахмурилась и упоминалась как «ленточная помощь плохому дизайну». – Alexey

ответ

2

При использовании фонового работника вы должны выполнять всю обработку, отличную от пользовательского интерфейса, в фоновом рабочем режиме; вы не должны использовать его для обновления пользовательского интерфейса при выполнении обработки в потоке пользовательского интерфейса.

Перемещая работу к обработчику DoWork BGW, вы освобождаете поток пользовательского интерфейса, чтобы он мог обрабатывать события пользовательского интерфейса, включая обновление индикатора выполнения.

+0

Боковой вопрос. Я переместил большинство из них в BGW, но теперь я должен загрузить обработанные значения в сетку (взаимодействие с пользовательским интерфейсом). Как передать значение графическому интерфейсу? GUI.Invoke? – Alexey

+1

@Alexey Как я уже говорил несколько раз, BGW предоставляет несколько событий для взаимодействия с пользовательским интерфейсом. Это * это целая причина для существующего * вместо прямого использования Thread. Если это будет результат операции, установите свойство «Результат» и используйте его в завершенном событии (которое выполняется в потоке пользовательского интерфейса) для обновления пользовательского интерфейса. Если это изменение пользовательского интерфейса, которое является частью периодических обновлений прогресса, используйте аспект его выполнения. Подробности и примеры всего этого можно увидеть на страницах MSDN по BGW. – Servy

+0

Я смущен, я задал этот вопрос.Просто так жареный, что я застрял в своих мыслях через progressReport. Полностью забыли о результате: D – Alexey

-2
private void btnCreate_Click(object sender, EventArgs e) 
    { 
     Progressbar1.Minimum = 1; 

     Progressbar1.Maximum = dt.Rows.Count; 

     Progressbar1.Value = 1; 

     Progressbar1.Step = 1; 


    for (int i = 1; i <= dt.Rows.Count; i++) 
    { 
      bool result=InsertUserdetails(Username); 

      if(result== true) 
      { 
       Progressbar1.PerformStep(); 
      } 
    } 
    } 
+1

Это делает длинную работу в потоке пользовательского интерфейса ... – Servy

+1

Это просто неправильно. – hattenn

3

Есть ли у меня еще какие-либо возможности? Да и нет. Лучшим вариантом является по-прежнему поставить время на узнать, как правильно использовать фонариста, это далеко самое легкое решение для этой проблемы.

Идите вперед и изучить эти ссылки:

Самое главное, чтобы установить это свойство:

bw.WorkerReportsProgress = true; 

И в DoWork-функции, убедитесь, что вы сообщить о достигнутом прогрессе в UI, как указано в примерах, связанных:

worker.ReportProgress((i * 10)); 

Кроме того, не забудьте обработать progresschanged событие в пользовательском интерфейсе:

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%"); 
} 

Вперед, и вы увидите: это довольно просто.

Смежные вопросы