Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 在UI线程上运行昂贵的操作时,保持UI可视化更新_Wpf_User Interface_Asynchronous_Dispatcher_Begininvoke - Fatal编程技术网

Wpf 在UI线程上运行昂贵的操作时,保持UI可视化更新

Wpf 在UI线程上运行昂贵的操作时,保持UI可视化更新,wpf,user-interface,asynchronous,dispatcher,begininvoke,Wpf,User Interface,Asynchronous,Dispatcher,Begininvoke,在我的WPF应用程序中,我需要在我的UI线程上运行一个昂贵的操作(我们称之为ExpensiveUIOperation()),我想让UI保持最新,以跟踪它的进度 为了跟踪进度,我只需要一个TextBlock,它的Text属性绑定到一个整数依赖属性PercentageComplete。在ExpensiveUIOperation()期间,我只需根据需要设置PercentageComplete的值 现在,我对线程有了足够的了解,知道如果我只是在我的UI线程上运行ExpensiveUIOperation(

在我的WPF应用程序中,我需要在我的UI线程上运行一个昂贵的操作(我们称之为
ExpensiveUIOperation()
),我想让UI保持最新,以跟踪它的进度

为了跟踪进度,我只需要一个
TextBlock
,它的
Text
属性绑定到一个整数依赖属性
PercentageComplete
。在
ExpensiveUIOperation()
期间,我只需根据需要设置
PercentageComplete
的值

现在,我对线程有了足够的了解,知道如果我只是在我的UI线程上运行
ExpensiveUIOperation()
,TextBlock将不会保持最新,因为UI线程将被阻止,停止任何接口更新

所以我想我可以像这样异步做:

Dispatcher.BeginInvoke(new Action(ExpensiveUIOperation), DispatcherPriority.Background);
但这仍然不起作用。在操作完成之前,文本块不会以可视方式更新

有没有办法做到这一点?


不幸的是,在这种情况下,我不能使用后台线程,因为该操作会大量使用UI线程所拥有的对象。

您被卡住了,UI操作必须在UI线程上进行,并且在这种情况下,不会发生UI更新。在WPF中,通过创建一个新的调度器框架(),您可以做一个“代码>应用程序。doStase,但这是危险的,在更新过程中,您将捕获UI,而不是一件好事。” 昂贵的UI操作真的是CPU密集型、仅UI的操作吗?例如,没有什么可以通过视图模型对象图完成,然后最终绑定到UI

不幸的是,在这种情况下,我不能使用后台线程,因为该操作大量使用UI线程拥有的对象


这不是像这样滥用UI线程的充分理由。在访问这些元素时使用Dispatcher(请参阅),或者将视图正确绑定到相关属性,甚至不需要这样做,因为更新会在内部排队到UI。

谢谢。我的“昂贵操作”构建了一个FixedDocument对象(创建它、添加FixedPage对象等)。从那以后,我了解到,因为FixedDocument是一个DispatcherObject,所以我必须在最终用于显示它的DocumentViewer的同一线程中创建它。因此,我需要在UI线程上执行此操作。我确实找到了另一个解决方案,一个类似情况的家伙在后台线程中创建了一个FixedDocument,将其序列化到磁盘,然后将其加载到UI线程中。但我现在找到了自己的解决方法。为此,我最终使用了ApplicationDoEvents方法。为了将危险降至最低,我在第二个UI线程上运行了整个操作。