C#中的协程

我正在寻找在c#中实现协程(用户调度线程)的方法。 当使用C ++时,我正在使用光纤。 我在互联网上看到光纤不存在于C#中。 我想获得类似的function。

有没有什么“正确”的方式来实现在c#中的协程?

我曾经想过使用线程来实现这一点,它在调度程序线程上获取单个执行互斥量+ 1,并为每个协程释放这个互斥量。 但是这看起来非常昂贵(它迫使每个协程之间的上下文切换)

我也看到了yield iterator的function,但据我所知,你不能在内部函数内产生(只在原始的ienumerator函数中)。 所以这对我来说不是好事。

编辑:你现在可以使用这些: .net中是否有一个纤维api?

我相信你应该看看.NET的Reactive Extensions 。 例如, 可以使用迭代器和yield语句来模拟协程 。

不过,你也可能想阅读这个问题 。

我相信在新的.NET 4.5 \ C#5中,async \ await模式应该能够满足您的需求。

 async Task<string> DownloadDocument(Uri uri) { var webClient = new WebClient(); var doc = await webClient.DownloadStringTaskAsync(url); // do some more async work return doc; } 

我build议查看http://channel9.msdn.com/Events/TechEd/Australia/Tech-Ed-Australia-2011/DEV411了解更多信息。; 这是一个很棒的介绍。

另外http://msdn.microsoft.com/en-us/vstudio/gg316360有一些很好的信息。;

如果您使用的是较早版本的.NET,则可以使用旧版.NET提供的Async CTP,以便在生产环境中使用它。 这是一个链接到CTP http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=9983

如果你不喜欢上面的选项,我相信你可以按照这里所述的asynchronous迭代器模式。 http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=9983

这里是使用线程来实现协程的例子:

所以我欺骗了。 我使用线程,但我只让其中一个运行在一个时间。 当我创build一个协程时,我创build一个线程,然后进行一些握手,以一个对Monitor.Wait()的调用结束,这会阻止协程线程 – 在解除阻塞之前它不会再运行。 当调用协程时,我执行一个以调用线程被阻塞结束的切换,并且协程线程可以运行。 同样的交接方式。

与其他实现相比,这些切换是昂贵的。 如果你需要速度,你会想写自己的状态机,并避免所有的上下文切换。 (或者你想使用光纤感知的运行时间 – 交换光纤是相当便宜的。)但是,如果你想expression代码,我认为协程有一些承诺。

你可能对这个隐藏了协程的用法感兴趣。 例如要读取一个文件:

 //Prepare the file stream FileStream sourceStream = File.Open("myFile.bin", FileMode.OpenOrCreate); sourceStream.Seek(0, SeekOrigin.End); //Invoke the task yield return InvokeTaskAndWait(sourceStream.WriteAsync(result, 0, result.Length)); //Close the stream sourceStream.Close(); 

这个库使用一个线程运行所有协程,并允许调用真正的asynchronous操作的任务。 例如调用另一个方法作为协程(也称为返回

 //Given the signature //IEnumerable<string> ReadText(string path); var result = new Container(); yield return InvokeLocalAndWait(() => _globalPathProvider.ReadText(path), container); var data = container.RawData as string;