2

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

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

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

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

“我会做什么:使用 aXamlWriter并将其序列FlowDocument化为XDocument. 序列化任务涉及Dispatcher,但是一旦完成,您可以根据需要对数据运行任意数量的古怪并行分析,并且 UI 中的任何内容都不会影响它。(同样,一旦它是一个XDocument你查询它XPath,这是一个非常好的锤子,只要你的问题实际上是钉子。)”

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

4

2 回答 2

1

对于任何未来的访问者,我都遇到了同样的问题,并通过这篇 文章解决了所有问题

最终做的是在后台线程上创建对象

            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...

希望它可以节省其他人一些时间:)

于 2019-04-10T14:13:28.333 回答
0

虽然不能真正回答详细说明您引用的作者的含义,但也许这可以解决您的问题:如果您将自己连接到 Application.Idle 事件中,您可以在那里一个一个地构建您的 FlowDocument。此事件仍在 UI 线程中,因此您不会遇到后台工作人员中的问题。尽管你必须小心不要一次做太多的工作,否则你会阻止你的应用程序。如果可以将生成过程分成小块,则可以在此事件中逐个处理这些块。

于 2012-04-25T10:02:29.503 回答