C#中的Fibers是否比迭代器更快,人们是否使用过它们?

8

所以我和一个同事聊起了fibers,并找到了这篇2003年的论文,其中描述了使用Fiber API在C#中实现协程。

这篇论文中Yield的实现是针对.NET 1.1的,因此它早于.NET 2.0中出现的yield return语法。

乍一看,这里的实现显然可能更快,并且可以很好地扩展到多个CPU。

有人用过吗?


2
我没有使用过它,但我对这个主题很感兴趣。这是一个在C#中使用轮询调度程序实现协程的不错例子:http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=71235c5a-3753-4bab-bdb0-334ab439afaf - jpbochi
2
顺便问一下,你对这个问题期望什么样的回答? - jpbochi
1
比什么“潜在更快”? - H H
并且请确保文本和问题标题匹配。 - H H
1
@jpbochi:确实,比C#迭代器更快。我期待像你给出的答案:协程对我来说是新的,纤程也是,我很想知道它们是否适用于高性能系统。 - Jeremy McGee
显示剩余3条评论
3个回答

8

我没有使用过它,但我对这个主题很感兴趣。这是C#中一种不错的协程实现,采用轮询调度程序:http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=71235c5a-3753-4bab-bdb0-334ab439afaf

顺便说一下,引用wikipedia的话,“纤程描述的本质上与协程相同”。据我所知,在C#中最接近协程(或纤程)的东西是迭代器。实际上,它们与协程非常相似。Lippert发布了关于迭代器的几个注意点。希望它们都不会对您需要的目的造成严重问题。


7
我曾使用基于yield的“协程”,不得不说它们很麻烦。问题在于,无论你想在哪里使用它们,你都被迫使用yield语法。不仅如此,除非你链接yield(父级yield子级的yield),否则你只能嵌套你的协程一层深度。这完全摧毁了协程的一个关键优势(完整的堆栈保存/恢复)。
我在C#中实现了一个基于纤程的协程系统,它工作得非常好,直到我遇到了异常。不幸的是,.Net运行时在操作系统线程中存储了大量的内部异常信息,这意味着使用操作系统纤程(和p/invoke)模拟多个线程将不起作用,除非你永远不会遇到任何异常。

在非托管代码中缺少异常处理的情况下,您能否通过在每个托管代码片段之前添加try / catch来解决? - Contango
1
这个回答很重要。它意味着你永远不能在生产中使用基于纤程的协程。 - usr
其实它只是意味着您必须嵌套执行,支持已处理和未处理的异常,同时在执行时传播异常时仅完全传播未处理的异常。基于异常的编程概念也应通过Fiber概念或合适的派生方式得到支持。 - Jay

2

一开始,协程就引起了我的注意...几天前,我正在寻找用于并行AsyncWCF方法调用的工作流解决方案,我发现真的很有趣:

http://csharperimage.jeremylikness.com/2010/03/sequential-asynchronous-workflows-in.html

这篇文章展示了在使用异步模式的 Silverlight 应用程序中创建/管理工作流的非常好的协程使用方法。

我不知道它与迭代器相比的速度如何,但对我来说,它就像是子程序的高级形式,可以在任务关键时刻提供非常有帮助的功能,而普通子程序无法为您提供并行执行任务的便利。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接