Это называется .Freeze ()
ложении WPF есть операция загрузки пользовательского элемента управления из отдельного файла с использованиемXamlReader.Load()
метод:
StreamReader mysr = new StreamReader(pathToFile);
DependencyObject rootObject = XamlReader.Load(mysr.BaseStream) as DependencyObject;
ContentControl displayPage = FindName("displayContentControl") as ContentControl;
displayPage.Content = rootObject;
Процесс занимает некоторое время из-за размера файла, поэтому пользовательский интерфейс останавливается на несколько секунд.
Для поддержания отзывчивости приложения я пытаюсь использовать фоновый поток для выполнения той части операции, которая не вызывается напрямую при обновлении пользовательского интерфейса.
При попытке использоватьBackgroundWorker
Я получил ошибку:Вызывающий поток должен быть STA, потому что многие компоненты пользовательского интерфейса требуют этого
Итак, я пошел другим путем:
private Thread _backgroundThread;
_backgroundThread = new Thread(DoReadFile);
_backgroundThread.SetApartmentState(ApartmentState.STA);
_backgroundThread.Start();
void DoReadFile()
{
StreamReader mysr3 = new StreamReader(path2);
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(Action<StreamReader>)FinishedReading,
mysr3);
}
void FinishedReading(StreamReader stream)
{
DependencyObject rootObject = XamlReader.Load(stream.BaseStream) as DependencyObject;
ContentControl displayPage = FindName("displayContentControl") as ContentControl;
displayPage.Content = rootObject;
}
Это ничего не решает, потому что все трудоемкие операции остаются в потоке пользовательского интерфейса.
Когда я пытаюсь вот так, делаю весь разбор в фоновом режиме:
private Thread _backgroundThread;
_backgroundThread = new Thread(DoReadFile);
_backgroundThread.SetApartmentState(ApartmentState.STA);
_backgroundThread.Start();
void DoReadFile()
{
StreamReader mysr3 = new StreamReader(path2);
DependencyObject rootObject3 = XamlReader.Load(mysr3.BaseStream) as DependencyObject;
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(Action<DependencyObject>)FinishedReading,
rootObject3);
}
void FinishedReading(DependencyObject rootObject)
{
ContentControl displayPage = FindName("displayContentControl") as ContentControl;
displayPage.Content = rootObject;
}
Я получил исключение:Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им. (в загруженном UserControl присутствуют другие элементы управления, которые могут выдавать ошибку)
Есть ли способ выполнить эту операцию таким образом, чтобы интерфейс реагировал?