A WPF aplicación tiene una operación de carga de un control de usuario a partir de un archivo separado usando XamlReader.Load()
método:XamlReader.Load en un hilo de fondo. ¿Es posible?
StreamReader mysr = new StreamReader(pathToFile);
DependencyObject rootObject = XamlReader.Load(mysr.BaseStream) as DependencyObject;
ContentControl displayPage = FindName("displayContentControl") as ContentControl;
displayPage.Content = rootObject;
El proceso lleva algún tiempo debido al tamaño del archivo, de modo de interfaz de usuario se congela durante varios segundos.
Para mantener la aplicación receptiva trato de usar una hebra de fondo para realizar la parte de la operación que no está directamente invocada en la actualización de la IU.
Al intentar utilizar BackgroundWorker
me dio un error: El subproceso de llamada debe ser STA, debido a que muchos componentes de interfaz de usuario requieren este
lo tanto, fui otra manera:
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;
}
Este no resuelve nada porque todas las operaciones que consumen tiempo permanecen en el hilo de UI.
Cuando trato de este tipo, por lo que todos los análisis en segundo plano:
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;
}
que tiene una excepción: El subproceso de llamada no se puede acceder a este objeto porque un subproceso diferente es el dueño. (en el UserControl cargado hay otros controles presentes que pueden dar el error)
¿Hay alguna manera de realizar esta operación de tal manera que la IU responda?
Utilice backgroundworker, asegúrese de que si va a modificar (establecer/agregar) cualquiera de los objetos que no están dentro del alcance en lugar del hilo en el que trabaja el Backgroundworker, usa una función/func o delegue ese trabajo y no intente configurarlo en el hilo de backgroundworker. Si algo hace su trabajo en su lugar el backgroundworker y cuando haya terminado tome el resultado (e.result) en el evento/método OnComplete y actualice su objeto en el subproceso UI. – Landern