gpt4 book ai didi

c# - XamlReader.Load 在后台线程中。是否可以?

转载 作者:太空狗 更新时间:2023-10-29 18:30:06 24 4
gpt4 key购买 nike

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;

由于文件的大小,该过程需要一些时间,因此 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;
}

这没有解决任何问题,因为所有耗时的操作都保留在 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;
}

我遇到了一个异常:调用线程无法访问此对象,因为另一个线程拥有它。(在加载的 UserControl 中存在其他控件,这些控件可能会提供错误)

有什么方法可以让 UI 响应来执行此操作?

最佳答案

让 XAML 加载后台线程本质上是行不通的。 WPF 组件具有线程关联性,一般来说只能从创建它们的线程中使用。因此,在后台线程上加载将使 UI 响应,但会创建无法插入 UI 线程的组件。

您在这里拥有的最佳选择是将 XAML 文件分解为更小的部分,然后将它们逐步加载到 UI 线程中,确保在每次加载操作之间允许消息泵。可能在 Dispatcher 对象上使用 BeginInvoke 来安排加载。

关于c# - XamlReader.Load 在后台线程中。是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5395264/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com