C# 在BackgroundWorker线程上创建FlowDocument

C# 在BackgroundWorker线程上创建FlowDocument,c#,serialization,backgroundworker,flowdocument,xamlwriter,C#,Serialization,Backgroundworker,Flowdocument,Xamlwriter,我需要从大量数据中动态生成FlowDocument。因为这个过程需要几分钟,所以我希望在后台线程上执行该操作,而不是让UI挂起 但是,我不能在非UI线程上生成FlowDocument,否则尝试插入矩形和图像会导致运行时错误,抱怨它不是STA线程 StackOverflow上有几个线程似乎涉及到与我相同的问题: 在第一个链接中,有人提出以下建议: “我要做的是:使用XamlWriter并将FlowDocument序列化为XDocument。序列化任务涉及Dispatcher,但一旦完成,就

我需要从大量数据中动态生成
FlowDocument
。因为这个过程需要几分钟,所以我希望在后台线程上执行该操作,而不是让UI挂起

但是,我不能在非UI线程上生成
FlowDocument
,否则尝试插入矩形和图像会导致运行时错误,抱怨它不是STA线程

StackOverflow上有几个线程似乎涉及到与我相同的问题:

在第一个链接中,有人提出以下建议:

“我要做的是:使用
XamlWriter
并将
FlowDocument
序列化为
XDocument
。序列化任务涉及
Dispatcher
,但一旦完成,就可以对数据执行任意多个古怪的并行分析,UI中的任何内容都不会影响它。(同样,一旦它是
XDocument
您就可以使用
XPath
查询它,这是一个非常好的工具,只要您的问题实际上是钉子就行了。)


有人能详细说明作者的意思吗?

虽然无法回答您的引文作者的意思,但也许这可以解决您的问题: 如果您将自己挂接到Application.Idle事件中,您可以在那里逐个构建流程文档。此事件仍在UI线程中,因此您不会遇到像后台工作人员那样的问题。 尽管你必须小心不要一次做太多的工作,否则你会阻止你的申请。
如果可以将您的生成过程分成小块,那么您可以在本次事件中逐个处理这些小块。

虽然您无法详细说明您的报价作者的意思,但这可能是您问题的解决方案: 如果您将自己挂接到Application.Idle事件中,您可以在那里逐个构建流程文档。此事件仍在UI线程中,因此您不会遇到像后台工作人员那样的问题。 尽管你必须小心不要一次做太多的工作,否则你会阻止你的申请。 如果可以将您的生成过程分成小块,那么您可以在本次活动中逐个处理这些小块。

供将来的访问者使用 多亏了这篇文章,我也遇到了同样的问题并解决了所有问题

最后要做的是在背景线程上创建对象

            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();
希望它能为其他人节省一些时间:)

供未来的访客使用 多亏了这篇文章,我也遇到了同样的问题并解决了所有问题

最后要做的是在背景线程上创建对象

            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();

希望它能为其他人节省一些时间:)

然后使用最终的FlowDocument创建XpsDocument,然后使用XAML中的DocumentViewer控件将其显示为FixedDocument序列。在开始在后台线程中生成内容之前,是否在ui线程上实例化FlowDocument?或者类似的东西?最终的FlowDocument然后用于创建XpsDocument,然后使用XAML中的DocumentViewer控件将其显示为FixedDocument序列。在开始在后台线程中生成内容之前,是否在ui线程中实例化FlowDocument?还是类似的?