Обновление интерфейса во время выполнения задачи - PullRequest
0 голосов
/ 19 ноября 2010

У меня есть следующий код:

        progressBar1.Minimum = 0;
        progressBar1.Maximum = Results.Count;

        foreach (MyClass cls in Results)
        {                
              progressBar1.Value += 1;

              // Go to DB and get large quantity of data
              cls.GetHistoryData();

        }

Что я хотел бы сделать, так это перенести обработку в другой поток, чтобы progressBar1 корректно обновлялся. Я нашел статью , которая подразумевает, что я должен иметь возможность использовать метод Invoke на индикаторе выполнения, но, похоже, его нет.

Ответы [ 5 ]

2 голосов
/ 19 ноября 2010

Если вы привязываете индикатор выполнения к свойству данных, вам не нужно переключать контекст потока вручную.Механизм связывания WPF сделает это автоматически для вас.

<ProgressBar Value={Binding Progress} />

А затем в вашей ветке:

foreach (MyClass cls in Results)
{                
      // databinding will automatically marshal to UI thread
      this.Progress++;
      cls.GetHistoryData();
}

В большинстве случаев это намного чище и менее подвержено ошибкам, чем сортировка на вашемсамостоятельно используя Dispatcher.Invoke или BackgroundWorker

2 голосов
/ 19 ноября 2010

Вы должны проверить BackgroundWorker класс. Он поддерживает прогресс и правильно обрабатывает связь между потоками.

0 голосов
/ 19 ноября 2010

Статья, на которую вы ссылаетесь, является примером winforms, но вы создаете приложение WPF. В вашем случае вам следует использовать класс Dispatcher, который вы получаете через свойство Dispatcher элемента управления.

0 голосов
/ 19 ноября 2010

попробуйте

progressBar1.Minimum = 0;
progressBar1.Maximum = Results.Count;

foreach (MyClass cls in Results)
{
    ThreadPool.QueueUserWorkItem((o) =>
             {
                 progressBar1.Dispatcher.BeginInvoke(
                     (Action) (() => progressBar1.Value += 1));
                 cls.GetHistoryData();
             });
}
0 голосов
/ 19 ноября 2010

Вы бы начали новую тему следующим образом:

Thread t1 = new Thread(methodnametocall);
   t1.start();

void methodnametocall()
{
   this.Invoke((MethodInvoker)delegate
   {

        control to update;
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...