.NET 中的多线程绘图?

问题描述 投票:0回答:2

编辑:澄清一下,我的主要目标是并发性,但不一定适用于多核机器)

我对并发的所有概念都相当陌生,但我发现我需要并行绘图例程,原因有很多:

  • 我想分别绘制图形的不同部分(背景刷新频率低于前景,保留在缓冲区中)。
  • 我想要控制优先级(UI 响应能力比绘制复杂图形更优先)。
  • 我想要多线程进行每帧绘图计算。
  • 我想为复杂的缓冲区绘图例程提供取消功能。

然而,作为一个初学者,我的代码很快就看起来一团糟,重构或修复错误变得如此尴尬,以至于我决定在做任何认真的事情之前需要更多地使用它。

所以,我想知道如何编写干净、易于维护的 .NET 多线程代码,当我第二天醒来后查看它时,它是有意义的。我遇到的最大问题是构建应用程序,以便所有部分都能以智能(而不是笨拙和黑客)的方式相互通信。

欢迎任何建议,但我更喜欢可以在空闲时间消化的资源(例如,不是关于并发性的 500 多页论文)和 C#/VB.NET,直到最新版本(因为我看到已经取得了进步)。基本上,我想要一些开门见山的东西,这样我就可以开始尝试我的玩具项目中的概念。

c# vb.net multithreading concurrency parallel-processing
2个回答
10
投票

但我发现我需要 平行绘图例程

三个字:不在WINDOWS下。

就这么简单。出于兼容性原因,标准 Windows 绘图根据定义是单线程的。任何 UI 控件(让我们坚持 .NET 世界)只能从其创建线程进行操作(因此实际上它比单线程更残酷 - 它只是一个特定的线程)。

你可以单独进行预计算,但真正的绘图必须从该线程完成。

除非您分配一个位图,在那里有自己的绘图,然后将其移交给 UI 线程以在窗口上绘制。

这与整个任务并行库等无关(我对此投了反对票),但回到了一个非常古老的要求,出于简单原因和兼容性而保留了该要求。这就是任何 UI 线程都作为单线程应用程序进入市场的原因。

还要注意,如果您自己实现多线程绘图,则会产生严重的影响。哪一个在视觉上获胜(留在前景)?使用多线程时,这实际上是无法确定的。不过你可以尝试一下。

在这种情况下:

  • 拥有自己的缓冲区和同步是必须的。除了最后一步(生成位图)之外,远离任何 Windows 级图形库(WPF 或 Winforms)。

  • DirectX 11 据说对多线程调用有一些支持,但我不确定这能走多远。


2
投票

任务并行库绝对是寻找简化代码的地方。我个人写了一篇(半长的)关于 Parallelism with .NET 4 的介绍,其中涵盖了很多有用的概念。

但是请注意,您可能会考虑将绘图保留为单线程。您应该尝试保持计算多线程,并在 GUI 线程上完成实际的绘图操作。

大多数绘图 API 要求所有实际绘图调用发生在同一同步上下文中。

话虽如此,使用像 ConcurrentQueue 这样的新集合类可以简化此类代码。尝试考虑许多线程(生产者)将“绘图操作”添加到共享的并发队列 - 以及一个线程(消费者)获取操作并执行它们。

这为您提供了一个可合理扩展但相当简单的设计,您可以在此基础上进行构建。

© www.soinside.com 2019 - 2024. All rights reserved.