【问题标题】:How to create a PathGeometry on a background task如何在后台任务上创建 PathGeometry
【发布时间】:2019-07-18 08:57:13
【问题描述】:

我有一个 WPF 应用程序,我在屏幕上绘制线条形状。我为此使用了 PathGeometry,我在代码 (C#) 中设置了它。一切正常,但是路径的构建相对昂贵,并且给我的 UI 带来了一些问题。因此,我尝试在后台任务中创建路径,但事实证明这是不可能的。 PathGeometry 类有一个 DependencyProperty 成员,看起来只能在 UI 线程上运行。 是否可以在后台任务上进行路径计算?

我正在事件处理程序上尝试这样的事情

    ...
    MyPath = await Task<PathGeometry>.Run( () => GeneratePath());
    ...

这里MyPath 是我的类中的一个属性,它数据绑定到我的 UI。当我运行代码时,我得到一个异常Must create DependencySource on same Thread as the DependencyObject。起初,我以为 MyPath 的设置没有发生在 UI 线程上,但后来我发现返回的 PathGeometry 包含异常。

【问题讨论】:

    标签: c# wpf path task


    【解决方案1】:

    PathGeometry 派生自Freezable,因此支持冻结后的跨线程访问。

    你可以这样冻结它:

    MyPath = await Task.Run(() =>
    {
        var path = GeneratePath();
        path.Freeze();
        return path;
    });
    

    或者最好在 GeneratePath 方法中调用 Freeze:

    private PathGeometry GeneratePath()
    {
        var path = new PathGeometry();
        ...
        path.Freeze();
        return path;
    }
    
    ...
    MyPath = await Task.Run(() => GeneratePath());
    

    【讨论】:

    • 有趣!我认为问题在于我在线程上使用了 PathGeometry。该解决方案证明在 UI 线程上使用返回的 PathGeometry 存在问题。我试过了,它有效。谢谢!
    【解决方案2】:

    最简单的方法是更改​​ GeneratePath() 方法以返回一个字符串(Path 的数据值),然后在异步方法返回后使用 Geometry.Parse() 将其转换为 UI 对象。

    【讨论】:

    • Geometry.Parse 然后将在 UI 线程上运行,并在 UI 线程上创建 PathGeometry,这显然是 OP 试图避免的。然而,由于 Parse 可能已经返回了一个冻结的几何图形,您也许也可以在任务中运行它。但是你为什么要序列化它呢?
    猜你喜欢
    • 1970-01-01
    • 2011-08-08
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多