在后台工作线程上创建流文档
本文关键字:创建 文档 线程 后台 工作 | 更新日期: 2023-09-27 18:32:15
我需要从大量数据动态生成FlowDocument
。由于该过程需要几分钟,因此我想在后台线程上执行操作,而不是挂起 UI。
但是,我无法在非 UI 线程上生成FlowDocument
,否则尝试插入矩形和图像会导致运行时错误,抱怨它不是 STA 线程。
StackOverflow上有几个线程似乎涉及我遇到的相同问题:
-
在后台进程中访问 WPF 流文档
-
WPF:无法在后台线程中加载UI吗?
在第一个链接中,有人建议如下:
"我要做的是:使用
XamlWriter
并将FlowDocument
序列化为XDocument
。序列化任务涉及Dispatcher
,但是一旦完成,您可以根据需要对数据运行任意数量的古怪并行分析,并且UI中的任何内容都不会影响它。(同样,一旦它是XDocument
,你就用XPath
查询它,这是一个相当不错的锤子,只要你的问题实际上是钉子。
有人可以详细说明作者的意思吗?
对于任何未来的访客我遇到了同样的问题,并通过这篇文章解决了所有问题品
最终要做的是在后台线程上创建对象
Thread loadingThread = new Thread(() =>
{
//Load the data
var documant = LoadReport(ReportTypes.LoadOffer, model, pageWidth);
MemoryStream stream = new MemoryStream();
//Write the object in the memory stream
XamlWriter.Save(documant, stream);
//Move to the UI thread
Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(Action<MemoryStream>)FinishedGenerating,
stream);
});
// set the apartment state
loadingThread.SetApartmentState(ApartmentState.STA);
// make the thread a background thread
loadingThread.IsBackground = true;
// start the thread
loadingThread.Start();
然后将结果作为 xaml 写入内存流中,以便我们可以在主线程中读回它
void FinishedGenerating(MemoryStream stream)
{
//Read the data from the memory steam
stream.Seek(0, SeekOrigin.Begin);
FlowDocument result = (FlowDocument)XamlReader.Load(stream);
FlowDocumentScrollViewer = new FlowDocumentScrollViewer
{
Document = result
};
//your code...
希望它能为其他人节省一些时间:)
虽然不是详细说明引用作者含义的答案,但也许这可以解决您的问题:如果您将自己挂接到 Application.Idle 事件中,则可以在那里逐个构建您的 FlowDocument。此事件仍位于 UI 线程中,因此不会像在后台辅助角色中那样遇到问题。虽然你必须小心不要一次做太多的工作,否则你会阻止你的应用程序。如果可以将生成过程分成小块,则可以在此事件中逐个处理这些块。