Как обновить Silverlight UI при обработке - PullRequest
0 голосов
/ 08 июля 2010

Я просмотрел несколько примеров, опубликованных в Интернете, но не могу ответить на мой вопрос.

У меня есть переменная 'p', которая увеличивается на 1 в цикле for. Я хочу, чтобы пользовательский интерфейс отображал ход вычислений (чтобы показать, как «р» увеличивается с 0 до 1000000). Я делаю вычисления в отдельном потоке и вызываю диспетчер для обновления ResultBox в пользовательском интерфейсе. Пример:

 int p=0;

 ...

 private void GO(object sender, System.Windows.RoutedEventArgs e)
 {
        new Thread(delegate()
        {
            DoWork();
        }).Start();

}

    void DoWork()
    {
        for (int i = 0; i < 1000; i++)
        {
            for (int j = 0; j < 10000; j++)
            {
                p++;
                this.Dispatcher.BeginInvoke(delegate { ResultBox.Text = p.ToString(); });
            }
        }

    }

По какой-то причине это не работает. Однако, когда я помещаю Thread.Sleep (1) перед этим. Диспетчер ... он работает как задумано. Означает ли это, что обновление пользовательского интерфейса (Dispatcher) вызывается слишком часто, поэтому оно зависает? Есть ли другой способ сделать это?

Спасибо

Ответы [ 2 ]

1 голос
/ 08 июля 2010

Почему бы не привязать свойство к вашему TextBox и обновить значение свойства вместо того, чтобы тыкать прямо в текстовое поле?

0 голосов
/ 08 июля 2010

Да, только выполнение p ++ в вашем цикле не займет много времени и в Silverlight, Dispatcher - это не что иное, как простая очередь с делегатами, и прежде чем silverlight сможет даже обновить и обработать его пользовательский интерфейс, вы перекачиваете слишком много значений в очередь. , Представьте себе, что произойдет, если вы продолжите добавлять путь в путь быстрее, чем очередь будет снята с очереди, и в итоге она достигнет максимального предела. И в конце концов это просто остановится. Если ваш p ​​++ заменяется более трудоемкой задачей, то вы можете получить хороший результат.

Вы должны знать, что наш глаз обычно может видеть только обновления со скоростью 30 кадров в секунду, более 30 обновлений в секунду вообще бесполезны, я предлагаю уменьшить количество обновлений для вашего просмотра до максимум 10 обновлений в секунду. производительность.

И для показа прогресса, я думаю, 1 обновления в секунду также достаточно. Сначала всегда отображайте обновления очень медленно, например

void DoWork() 
{ 
    for (int i = 0; i < 1000; i++) 
    { 
        for (int j = 0; j < 10000; j++) 
        { 
            p++; 
            if((p % 1000)==0){
                 this.Dispatcher.BeginInvoke(delegate 
                      { ResultBox.Text = p.ToString(); });
            } 
        } 
    } 

} 

Теперь вы можете увеличивать / уменьшать 1000 до некоторого подходящего множителя 10, чтобы настроить визуальное обновление.

...