有人在大型或中型项目中使用过。net开源实现Mono吗?我想知道它是否已经为现实世界的生产环境做好了准备。它是否稳定、快速、兼容……足够用了吗?将项目移植到Mono运行时是否需要花费大量的精力,或者它是否真的足够兼容,只需要为微软的运行时编写代码就可以了?


当前回答

不幸的是,对于我们正在构建的应用程序类型来说,Mono似乎还没有准备好投入生产。总的来说,我们对它印象深刻,对它在Windows和EC2机器上的性能印象深刻,然而,我们的程序在Windows和linux上都因垃圾收集错误而崩溃。

错误信息是:“GC中的致命错误:太多堆节”,这里是一个链接,其他人以略微不同的方式遇到这个问题:

http://bugzilla.novell.com/show_bug.cgi?id=435906

我们在Mono中运行的第一段代码是我们开发的一个简单的编程挑战……代码将大约10mb的数据加载到一些数据结构(例如HashSets)中,然后对数据运行10个查询。我们将这些查询运行100次以计算它们的时间并获得平均值。

在Windows上,代码在第55个查询时崩溃。在linux上它可以工作,但一旦我们转移到更大的数据集,它也会崩溃。

这段代码非常简单,例如,把一些数据放入哈希集,然后查询这些哈希集等,所有本机c#,没有不安全的,没有API调用。在微软CLR上,它从来不会崩溃,在巨大的数据集上运行1000次也很好。

我们的一个人给米格尔发了邮件,附上了导致问题的代码,还没有回复。:(

似乎很多人也遇到过这个问题,但没有解决方案——有人建议用不同的GC设置重新编译Mono,但这似乎增加了崩溃的阈值。

其他回答

这实际上取决于您从. net框架中使用的名称空间和类。我有兴趣将我的一个windows服务转换到我的电子邮件服务器(Suse)上运行,但我们遇到了几个尚未完全实现的api的硬障碍。Mono网站上的某个地方有一个图表,列出了所有的课程及其完成程度。如果你的申请被覆盖了,那就去申请吧。

当然,像任何其他应用程序一样,在做出全面承诺之前要进行原型设计和测试。

我们遇到的另一个问题是授权软件:如果您引用的是别人的DLL,那么您就无法通过编写代码来绕过隐藏在该程序集中的不兼容性。

这里有几个场景需要考虑:(a)如果你正在移植一个现有的应用程序,并且想知道Mono是否足够好来完成这个任务;(b)你开始写一些新代码,你想知道Mono是否足够成熟。

对于第一种情况,您可以使用Mono迁移分析工具(Moma)来评估您的应用程序距离在Mono上运行还有多远。如果评估结果令人满意,你就应该开始测试和QA工作,并准备发布。

如果你的评估返回的报告强调了在Mono中缺失的功能或语义上的显著差异,你将不得不评估代码是否可以改编,重写,或者在最坏的情况下,你的应用程序是否可以在功能减少的情况下工作。

According to our Moma statistics based on user submissions (this is from memory) about 50% of the applications work out of the box, about 25% require about a week worth of work (refactoring, adapting) another 15% require a serious commitment to redo chunks of your code, and the rest is just not worth bothering porting since they are so incredibly tied to Win32. At that point, either you start from zero, or a business decision will drive the effort to make your code portable, but we are talking months worth of work (at least from the reports we have).

如果您从头开始,情况就简单多了,因为您将只使用Mono中存在的api。只要你继续使用支持的堆栈(基本上是。net 2.0,加上3.5的所有核心升级,包括LINQ和System)。核心,加上任何Mono跨平台api)你会很好。

每隔一段时间,你可能会在Mono中遇到bug或限制,你可能不得不解决它们,但这与其他系统没有什么不同。

至于可移植性:ASP。NET应用程序更容易移植,因为它们对Win32几乎没有依赖,你甚至可以使用SQL server或其他流行的数据库(Mono中有很多捆绑的数据库提供商)。

窗户表单移植有时比较棘手,因为开发人员喜欢逃离。net沙盒,用P/Invoke来配置一些有用的东西,比如用wParam中BCD格式编码的两个bezier点来表示改变光标闪烁速率。或者类似的垃圾。

不幸的是,对于我们正在构建的应用程序类型来说,Mono似乎还没有准备好投入生产。总的来说,我们对它印象深刻,对它在Windows和EC2机器上的性能印象深刻,然而,我们的程序在Windows和linux上都因垃圾收集错误而崩溃。

错误信息是:“GC中的致命错误:太多堆节”,这里是一个链接,其他人以略微不同的方式遇到这个问题:

http://bugzilla.novell.com/show_bug.cgi?id=435906

我们在Mono中运行的第一段代码是我们开发的一个简单的编程挑战……代码将大约10mb的数据加载到一些数据结构(例如HashSets)中,然后对数据运行10个查询。我们将这些查询运行100次以计算它们的时间并获得平均值。

在Windows上,代码在第55个查询时崩溃。在linux上它可以工作,但一旦我们转移到更大的数据集,它也会崩溃。

这段代码非常简单,例如,把一些数据放入哈希集,然后查询这些哈希集等,所有本机c#,没有不安全的,没有API调用。在微软CLR上,它从来不会崩溃,在巨大的数据集上运行1000次也很好。

我们的一个人给米格尔发了邮件,附上了导致问题的代码,还没有回复。:(

似乎很多人也遇到过这个问题,但没有解决方案——有人建议用不同的GC设置重新编译Mono,但这似乎增加了崩溃的阈值。

我个人在黄金时段使用Mono。 我运行单服务器处理千兆字节的udp/tcp数据处理相关任务,不能再高兴了。

有一些特殊之处,其中最烦人的事情之一是,由于Mono的当前状态,你不能“构建”你的msbuild文件:

MonoDevelop (the IDE) has some partial msbuild support, but will basically bork on any "REAL" build conf beyond a simple hello-world (custom build tasks, dynamic "properties" like $(SolutionDir), real configuration to name a few dead-ends) xbuild which SHOULD have been the mono-supplied-msbuild-fully-compatible-build-system is even more horrible, so building from the command line is actually a worse experience than using the GUI, which is a very "unorthodox" state of the union for Linux environments...

一旦/在你的东西真正构建的过程中,你可能会看到一些应该支持的代码的荒野:

编译器在某些构造上出错 一些更高级的/新的。net类向你抛出意想不到的垃圾(XLinq的人吗?) 一些不成熟的运行时“特性”(3GB堆限制在x64…WTF !)

但heaving表示,一般来说,事情很快就会开始起作用,而且解决方案/变通方法很多。

一旦你克服了这些最初的障碍,我的经验是,mono很摇滚,并在每次迭代中变得越来越好。

我有使用mono运行的服务器,每天处理300GB的数据,有大量的p/调用,通常来说要做大量的工作,并且保持5-6个月,即使使用“最先进的”mono。

希望这能有所帮助。

MoMA是一个很好的工具,就像其他人建议的那样。目前最大的不兼容性来源是将DllImport(或P/Invoke)导入Win32库的应用程序。有些程序集没有实现,但大多数程序集仅适用于windows,在Linux上确实没有意义。我认为可以肯定地说,大多数ASP。NET应用程序可以在Mono上运行,只需进行有限的修改。

(披露:我为Mono本身做出了贡献,也编写了在Mono上运行的应用程序。)