WPF 执行两个交替的 UI 任务
本文关键字:UI 任务 两个 执行 WPF | 更新日期: 2023-09-27 18:36:30
我有一个带有Helix3DToolkit Graphics的WPF UI。
我那里有两个按钮,
第一个按钮 - 在其中添加一些 Visual3D 对象。
第二个按钮 - 使用
屏幕截图的代码:
Viewport3DHelper.Export(vp.Viewport, filename);
所有这些都可以手动正常工作。但现在我想让它自动化。(按钮 1 和 2 的几轮交替操作,即我只想按一个按钮,这将添加一些框、保存屏幕截图、添加更多、保存屏幕截图等)
我可以使用以下命令以编程方式控制按钮:
ButtonAutomationPeer peer = new ButtonAutomationPeer(MyButton);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();
但是当我这样做时,我得到的只是同一 UI 的多个副本。(我相信这是由于 UI 线程的性质)
我找到了一个部分解决方案,即使用,
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
CancellationToken cancellationToken = new CancellationToken();
Task.Factory.StartNew(() => GetScreenShotAction()).ContinueWith(w =>
{
AddBoxes();
}, cancellationToken, TaskContinuationOptions.None, scheduler);
但是,这也不能正常工作(当我只截取 2 张屏幕截图时,它是随机工作的,但当它超过 2 张时永远不会)。这可能是因为之前和之后的操作都在 UI 线程上。
关于如何完成此操作的任何想法将不胜感激。
此外,我将VC# 2010与.NET 4框架一起使用。所以不能使用async
和await
.
谢谢!
更新
我已经在使用,this.Dispatcher.Invoke((Action)(() => { ... }));
GetScreenShotAction
方法。而且,AddBoxes
的另一个操作在同一线程上。
此外,它是随机工作的,所以我猜测因为我正在调用调度程序,所以两者在技术上仍然在同一线程上发生。
我怀疑您需要等待 UI 呈现(在通过添加按钮等方式修改可视化树之后)才能截取屏幕截图。
本文介绍如何将调度程序与DispatcherPriority.Render
一起使用,以获取代码以等待所有呈现完成,然后再继续。
引用文章:
当调度程序优先级设置为渲染(或更低)时,代码将 然后执行具有该优先级或更高优先级的所有操作。 在 例如,代码已经设置了 label1。内容到别的东西, 这将导致渲染操作。 所以通过打电话 Dispatcher.Invoke,代码本质上要求系统执行所有 具有 Render 或更高优先级的操作,因此控件将 然后呈现自身(绘制新内容)。 之后,它将 然后执行提供的委托(这是我们的空方法)。
刷新扩展方法的代码:
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
}
使用它像这样:
AddBoxes();
MyControlContainer.Refresh();
TakeScreenShot();
MyControlContainer
在哪里是UIElement
,也许是您添加盒子的容器?
您使用Task
多线程操作,您走在正确的轨道上。问题是您需要在正确的Thread
上Invoke
代码。使用Dispatcher
(也称为 WPF UI 线程)通过Application.Current.Dispatcher
根据需要调用Invoke()
或BeginInvoke()
来执行此操作。