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框架一起使用。所以不能使用asyncawait.

谢谢!

更新

我已经在使用,this.Dispatcher.Invoke((Action)(() => { ... })); GetScreenShotAction方法。而且,AddBoxes的另一个操作在同一线程上。

此外,它是随机工作的,所以我猜测因为我正在调用调度程序,所以两者在技术上仍然在同一线程上发生。

WPF 执行两个交替的 UI 任务

我怀疑您需要等待 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多线程操作,您走在正确的轨道上。问题是您需要在正确的ThreadInvoke代码。使用Dispatcher(也称为 WPF UI 线程)通过Application.Current.Dispatcher根据需要调用Invoke()BeginInvoke()来执行此操作。