2015-05-26 4 views
2

Здравствуйте, у меня возникли проблемы с обновлением привязки из фонового потока. Я показываю индикатор IsBusy, в то время как некоторая обработка фона продолжается, а затем скрывает индикатор по завершении.Связывание завершается при вызове из фонового потока

Обратите внимание, если я установил IsLoading в false внутри моего рабочего фона (но, вызвав его в потоке пользовательского интерфейса), он никогда не обновляет пользовательский интерфейс.

Если я вызываю его сразу же после, в потоке пользовательского интерфейса. Оно работает.

Что мне не хватает?

 private void BeginValidation() 
    { 
     m_ValidationWorker = new BackgroundWorker(); 

     m_ValidationWorker.WorkerReportsProgress = false; 
     m_ValidationWorker.DoWork += (_sender, _args) => 
     { 
      foreach (DataRecord record in DatabaseViewModel.Instance.Records) 
      { 
       record.Init(); 

       Application.Current.Dispatcher.Invoke(()=> { record.IsLoading = false; }); //THIS DOESN'T WORK 
      } 
     }; 

     m_ValidationWorker.RunWorkerCompleted += (_sender, _args) => 
     { 
      foreach (DataRecord record in DatabaseViewModel.Instance.Records) 
      { 
      record.IsLoading = false;//THIS WORKS 
      } 
     }; 

     m_ValidationWorker.RunWorkerAsync(); 
    } 

И xaml только для информации.

  <telerik:RadBusyIndicator IsBusy="{Binding FirstRecord.IsLoading}" IsIndeterminate="True" DisplayAfter="0" BusyContent="Processing" Style="{StaticResource RadBusyIndicatorStyle}"> 
      <Grid> 
        <ScrollViewer HorizontalScrollBarVisibility="Disabled" Padding="5"> 
         <ItemsControl ItemsSource="{Binding FirstRecord.Fields}" ItemTemplateSelector="{StaticResource FormView_TypeSelector}"/> 
        </ScrollViewer> 
      </Grid> 
     </telerik:RadBusyIndicator> 
+2

Вся * точка * BGW предназначена для работы с не-UI в обработчике DoWork и обновлении пользовательского интерфейса с использованием других обработчиков. Вы проиграли всю цель использования BGW, если вы проигнорируете все другие события и вручную маршалируете в поток пользовательского интерфейса. – Servy

+0

Вы должны обновить пользовательский интерфейс в обработчике событий 'ProgressChanged'. В обработчике 'DoWork' вам нужно будет вызвать метод' _sender.ReportProgress', который запускает событие 'ProgressChanged'. Я считаю, что вам не нужно выполнять маршалинг в обработчике событий ProgressChanged, поскольку он уже маршалирован. –

ответ

0

Вы получаете текущий диспетчер из потока, отличного от UI, и пытаетесь его использовать.

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

+0

Я не совсем уверен, что понимаю. Как заставить BGW обрабатывать сортировку в потоке пользовательского интерфейса? – Asheh

+0

@Asheh Вы показали, как это сделать в вашем вопросе, когда вы показали пример, который действительно сработал. В частности, вы обновляете пользовательский интерфейс в 'RunWorkerCompleted', а не' DoWork'. – Servy

+0

Вы говорите, что я должен разделить каждую запись на отдельный поток? Это создаст более 10 000 потоков. Я не хочу ждать, пока загрузится КАЖДАЯ запись, прежде чем каждая запись будет проинформирована о ее загрузке. – Asheh

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