2012-03-09 3 views
0

Im пытается обновить индикатор выполнения при выполнении некоторых проверок типов данных в отдельном потоке, и, кажется, существует задержка между тем, какое значение имеет индикатор выполнения, и значение, которое на самом деле отображается.control.invoke() issue

Следующий код выполняется потоком без GUI и используется для поднять событие.

protected virtual void OnUpdateProgressBar(object sender, ProgressBarEventArgs e) 
    { 
     EventHandler<ProgressBarEventArgs> TempHandler = UpdateProgressBar; 

     //Avoid possible race condition. 
     if (TempHandler != null) 
     { 
      TempHandler(this, e); 
     } 
    } 

Я создал отдельный класс для обновления индикатор выполнения и когда я создаю экземпляр этого, я передать ссылку на прогресс-бар. Ниже приведен весь класс.

public class ProgressBarChanged 
{ 
    ProgressBar statusBar; 

    public ProgressBarChanged(ProgressBar pb) 
    { 
     statusBar = pb; 
     statusBar.Value = 0; 
    } 
    public ProgressBarChanged() 
    { 
    } 

    public void subscribeToEvent(DataVerification test) 
    { 
     test.UpdateProgressBar += new EventHandler<ProgressBarEventArgs>(incrementPB); 
    } 

    public void incrementPB(object sender, ProgressBarEventArgs e) 
    { 
     Action action =() => 
     { 
      if (e.CurrentRow == e.FinalRow - 10) 
      { 
       int i = 5; 
      } 
      statusBar.Maximum = e.FinalRow; 
      statusBar.Value = e.CurrentRow; 
     }; 

     if(statusBar.InvokeRequired) 
      statusBar.Invoke(action); 
     else 
      action(); 
    } 
} 

Я загрузил снимок экрана, показывающий индикатор выполнения и фактические значения. Любые идеи ???

Благодаря

enter image description here

+0

Вы пробовали использовать 'statusBar.Invoke (incrementPB, sender, e);'? – Steve

+0

Пробовал и статусBar.Invoke (incrementPB, sender, e); и statusBar.Invoke (incrementPB (отправитель, e)); ни работать. –

+0

@ Ken2K, спасибо за сортировку изображения. –

ответ

3

Progessbar - это простая обратная связь с пользователем, а не с точным инструментом. Это пустышка.

Он также включает в себя собственную асинхронную логику для обновления экрана (независимо от цикла сообщений). Это заставляет его немного отставать.

В чем дело?

Чтобы получить более точные результаты, разделите свой диапазон на < 100 сегментов и сделайте меньше обновлений.

+0

@ В настоящее время событие становится поднятым после обработки каждой строки = 130 000 раз. плохо попробуйте, как вы предположили, и поднимает его менее 100 раз и видит, решает ли это проблему.Спасибо за вашу помощь –

+2

@HansRudel Если значение обновляется только 100 раз (не 130k раз), это также значительно снизит потребление процессора, поэтому это хорошая идея. – ken2k

+0

@ ken2k: Хорошо отметил, спасибо. –

0

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

+0

: Спасибо, что ответили. Согласно сообщению г-на Скита здесь http://stackoverflow.com/questions/229554/whats-the-difference-between-invoke-and-begininvoke, хотя поток будет ждать, пока графический интерфейс обработает обновление строки выполнения. Или это изменит внутреннее значение, а затем потребуется время, чтобы фактически показать обновление? Если это так? –

+0

Поток будет ждать, пока PB не примет новое значение_. Визуальное обновление происходит отдельно. –

+0

Попробуйте вызвать Refresh после каждого изменения значения (но это не очень оптимально для обновления progbar таким образом). – ebutusov

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