Невозможно использовать объект DependencyObject, принадлежащий другому потоку, чем его родительский объект Freezable

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

Здесь я создаю свою тему:

public void Start()
    {

         if (_parent != null)
             _parent.IsEnabled = false;

         _thread = new Thread(RunThread);

         _thread.IsBackground = true;
         _thread.SetApartmentState(ApartmentState.STA);
         _thread.Start();

         _threadStarted = true;
         SetProgressMaxValue(10);

         Thread th = new Thread(UpdateProgressBar);
         th.IsBackground = true;
         th.SetApartmentState(ApartmentState.STA);
         th.Start();
    }

И метод потока:

private void RunThread()
    {

        _window = new WindowBusyPopup(IsCancellable);
        _window.Closed += new EventHandler(WaitingWindowClosed);
        _window.ShowDialog();
    }

Теперь момент, который выполняется, я получаю эту ошибку:

Невозможно использовать объект DependencyObject, принадлежащий другому потоку, чем его родительский объект Freezable.

Любая помощь будет оценена:)

2 ответа

Попробуйте использовать свойство Dispatcher формы. Dispatcher.BeginInvoke(...)

Или просто используйте класс BackgroundWorker, потому что у него есть метод ReportProgress() для отчета о прогрессе. Это вызовет событие ProgressChanged, когда вы сможете обновить значение индикатора выполнения или что-то еще...

Невозможно использовать объект DependencyObject, принадлежащий другому потоку, чем его родительский объект Freezable.

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

В вашем случае это выглядит как второй поток Thread th = new Thread(UpdateProgressBar); пытается манипулировать пользовательским интерфейсом в WindowBusyPopup. Поскольку всплывающее окно принадлежит другому потоку, вы получаете это исключение.

Возможное решение: (как я вижу, вы не показываете реализацию функции UpdateProgressBar)

private void UpdateProgressBar()
{
if(_window != null) /* assuming  you declared your window in a scope accesible to this function */
_window.Dispatcher.BeginInvoke(new Action( () => {
// write any code to handle children of window here
}));
}
Другие вопросы по тегам