TaskCapableComponent vs Parallel.For 该怎么选?
在Rhino6更新之后,Grasshopper加入了一个新的API —— TaskCapableComponent,使得电池对多线程有了更深度的支持。官方也早在2018年就做了文档和简单的例子,让大家能够更好的针对使用这个组件进行开发(官方例子链接)。
以下Grasshopper简称GH
不过官方的例子有点奇怪,为什么我算一个斐波那契数列还要多线程?这玩意儿多线程有啥意义?再进一步说,由于GH的整个画布的单线程架构,我在这个电池内部做计算密集型为什么不直接一个Parallel.For解决还需要实现这么复杂的接口?TaskCapableComponent与Parallel.For到底有什么区别?下面就一一解答。
关于为什么官例要用斐波那契数列,为什么这玩意儿要多线程,有什么意义,这个点放在最后说,因为当把TaskCapableComponent和Parallel.For它俩的区别说完之后,其原因就不言自明了。
注意: 以下代码均需要使用System.Threading.Tasks命名空间,即
using System.Threading.Tasks;
本文所有代码详见 https://codechina.youkuaiyun.com/bwkair/taskcapablevsparallel
Task Capable Component 要怎么实现
首先来看如何实现一个TaskCapableComponent:(笔者这里就不用官例的斐波那契数列了,采用一个很常规的Thread.Sleep()来实现)
-
首先第一步创建一个Grasshopper电池项目

-
将新建立的GH电池类的继承由
public class TaskCapableComponentExampleComponent : GH_Component改为
public class TaskCapableComponentExampleComponent : GH_TaskCapableComponent<string>其中,
string是每个线程任务执行完成后的返回值的类型,可以认为是等同于电池输出的数据类型。为什么会多出这个?因为GH多线程电池是基于C#中的Task类架构的,主要运算部分会被封装成一个Task类来进行分发。由于我们在GH内做的除开“在Rhino窗口进行图形预览绘制”以外的操作,都是有数据需要输出的,即我们希望使用多线程执行的任务是需要有数据返回的,而这个有返回值的Task类“就是需要用
Task<T>”泛型类来封装,此时T就是返回的值的类型。总之,需要在GH电池的输出端输出什么类型的数据,这个T就是对应的类型。
更多有关于Task类的知识参照微软官方链接,此处不进行展开。
-
现在我们已经完成了一个支持多线程的电池架构。
?
“就这?”
需要做的改动当然不止于此了。目前仅仅是完成了“架构”部分的改动,电池是支持多线程了,但是我们的代码并没有真正地“实现多线程”。
实现多线程需要对电池的主运算部分SolveInstance()进行相应的重构。下面是开发文档的说明:
We will want to break the current flow of a component’s SolveInstance method into three distinct steps:
- Collect input data
- Compute results on given data
- Set output data
—— Steve Baer and Scott Davidson @Rhino Dev. Docs
译:
(要实现TaskCapableComponent的设计,)我们希望把原来电池的SolveInstance内部的程序流重组成为具有3个十分明显特征的步骤:
- 从输入端获取数据
- 由获取的数据运行所需要的计算
- 将计算结果输出
要我说,这其实是废话,因为本质上非多线程电池的对数据处理的逻辑简直是一模一样。我们先把非多线程的电池代码放上
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddIntegerParameter("Seconds", "s", "", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddTextParameter("Output", "o", "", GH_ParamAccess.item);
}
protected override void Solv

本文比较了Grasshopper中TaskCapableComponent与Parallel.For在多线程应用上的区别。通过具体实例展示了两种方法的实现过程及性能表现。
最低0.47元/天 解锁文章
2098

被折叠的 条评论
为什么被折叠?



