rem*_*rem 8 c# wpf multithreading xamlreader
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;
Run Code Online (Sandbox Code Playgroud)
由于文件的大小,该过程需要一些时间,因此UI会冻结几秒钟.
为了保持应用程序响应,我尝试使用后台线程来执行在UI更新中不直接调用的操作部分.
当BackgroundWorker我尝试使用时出现错误:调用线程必须是STA,因为许多UI组件都需要这个
所以,我走另一条路:
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;
}
Run Code Online (Sandbox Code Playgroud)
这解决了什么,因为所有耗时的操作都保留在UI线程中.
当我尝试这样做时,在后台进行所有解析:
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;
}
Run Code Online (Sandbox Code Playgroud)
我有一个例外:调用线程无法访问此对象,因为另一个线程拥有它.(在加载的UserControl中还有其他控件可能会出错)
有没有办法以这样的方式执行此操作UI要响应?
让XAML加载后台线程本质上是一个非首发.WPF组件具有线程亲和性,通常只能从创建它们的线程中使用.因此,在后台线程上加载会使UI响应,但会创建无法插入UI线程的组件.
您在这里拥有的最佳选择是将XAML文件分解为更小的片段,并在UI线程中逐步加载它们,确保在每次加载操作之间允许消息泵.可能BeginInvoke在Dispatcher对象上使用来安排负载.
| 归档时间: |
|
| 查看次数: |
2376 次 |
| 最近记录: |