2014-01-12 2 views
1

Я внедрил решение из вопроса переполнения стека Implement progressbar in this simple WPF application.WPF и фоновый рабочий и вызывающая нить должны быть STA

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

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

Я пытался поставить атрибут [STAThread] на MainWindow code-behind, а также внутри застройщик MainWindowViewModel. В обоих случаях ничего не изменилось.

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

Update После нажатия пользователя команды в ViewModel вызова метода LoadData

private void LoadData(string searchBy) 
{ 
    IsBusy = true; 
    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += (o, ea) => 
    { 
     switch (searchBy) 
     { 
      // WCF call to load data 
     } 
    } 

    worker.RunWorkerCompleted += (o, ea) => 
    { 
     IsBusy = false; 
    }; 

    worker.RunWorkerAsync(); 
+0

Где вы строите? BackgroundWorker? – Douglas

+1

«вызывающий поток» в сообщении не является вашим потоком пользовательского интерфейса. Это поток обратного вызова WCF. Вам необходимо мобилизовать вызов из этого фонового потока в поток пользовательского интерфейса с помощью Dispatcher, SynchronizationContext и т. Д. –

+0

@Douglas Я создаю BackgroundWorker после нажатия кнопки для загрузки данных с помощью вызова wcf. – user1765862

ответ

6

Существует множество дубликатов этой проблемы в переполнении стека. Например, this question.

Нижняя линия - в любое время, когда вы создаете компоненты пользовательского интерфейса, вы должны использовать резьбу однопоточной квартиры (STA). Исходные работники не являются STA. Таким образом, вы не можете создавать компоненты пользовательского интерфейса в фоновом режиме. Вы не можете обновлять компоненты пользовательского интерфейса от фоновых работников. Фоновые работники предназначены для запуска в фоновом режиме (большой сюрприз там), возможно, чтобы хруст данных и вернуть результат позже.

+0

Итак, когда фоновому работнику требуется некоторое взаимодействие с пользователем, нет способа его получить? –

+0

Фоновый работник по определению не требует взаимодействия с пользователем. У вас есть логическая проблема с вашим дизайном, который необходимо решить. – theMayer

3

Я думаю, вам нужно использовать Application.Current.Dispatcher.BeginInvoke(action). Это обновление пользовательского интерфейса из фонового потока.

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