代码之家  ›  专栏  ›  技术社区  ›  wvdschel

Mono准备好迎接黄金时段了吗?[关闭]

  •  314
  • wvdschel  · 技术社区  · 18 年前

    有人用过开源的Mono吗。NET在大型或中型项目上的实现?我想知道它是否已经为现实世界的生产环境做好了准备。它稳定、快速、兼容吗。…足够使用吗?将项目移植到Mono运行时需要付出很多努力吗, 真正地 兼容到足以在微软的运行时运行已经编写好的代码吗?

    17 回复  |  直到 5 年前
        1
  •  402
  •   jjnguy Julien Chastang    17 年前

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

    对于第一种情况,您可以使用 Mono Migration Analyzer tool (Moma)评估你的应用程序离在Mono上运行还有多远。如果评估结果令人满意,您应该开始测试和QA,并准备发货。

    如果您的评估返回一份报告,突出显示Mono中缺失或语义上存在显著差异的功能,您将不得不评估代码是否可以调整、重写,或者在最坏的情况下,您的应用程序是否可以在功能减少的情况下工作。

    根据我们基于用户提交(来自内存)的Moma统计数据,大约50%的应用程序可以开箱即用,大约25%需要大约一周的工作(重构、调整),另外15%需要认真致力于重做代码块,其余的不值得费心移植,因为它们与Win32非常紧密地联系在一起。在这一点上,要么你从零开始,要么一个业务决策将推动你的代码可移植,但我们谈论的是几个月的工作(至少从我们的报告来看)。

    如果你从头开始,情况会简单得多,因为你只会使用Mono中存在的API。只要你继续使用支持的堆栈(几乎是.NET 2.0,加上3.5中的所有核心升级,包括LINQ和System.core,再加上任何Mono跨平台API),你就没事了。

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

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

    窗户。表单移植有时更棘手,因为开发人员喜欢逃避。NET沙箱和P/调用他们的大脑来配置一些有用的东西,比如改变光标闪烁率,用wParam中BCD形式编码的两个bezier点来表示。或者像这样的垃圾。

        2
  •  65
  •   Ufuk Hacıoğulları    13 年前

    它的覆盖范围相当广泛。NET 4.0,甚至包括中的一些功能。NET 4.5 API,但由于API被弃用、创建了新的替代方案或范围太大,我们选择不实现一些领域。以下API在Mono中不可用:

    • Windows演示文稿基础
    • Windows Workflow Foundation(两个版本都没有)
    • 实体框架
    • 标准Web服务堆栈中的WSE1/WSE2“附加组件”

    此外,我们的WCF实现仅限于Silverlight支持的内容。

    检查特定项目的最简单方法是运行 Mono Migration Analyzer (MoMA) 。好处是它会通知Mono团队阻止您使用Mono的问题(如果有的话),这让他们可以优先考虑他们的工作。

    我最近在SubSonic上运行MoMA,只发现了一个问题——Nullable类型的奇怪使用。这是一个庞大的代码库,因此其覆盖范围相当可观。

    Mono正在积极使用 several commercial as well as open source products 。它在一些大型应用程序中使用,例如 Wikipedia and the Mozilla Developer Center ,并已用于嵌入式应用程序,如Sansa MP3播放器,并为数千款已发布的游戏提供动力。

    在语言层面, the Mono compiler is fully compliant with the C# 5.0 language specification .

        3
  •  39
  •   Henrik Heimbuerger Kenneth Reitz    15 年前

    在桌面端,如果你承诺使用GTK#,Mono的工作效果很好。窗户。表单实现仍然有点缺陷(例如,TrayIcon不起作用),但它已经走了很长的路。此外,GTK#是一个比Windows窗体更好的工具包。

    在web端,Mono已经实现了足够的ASP。NET可以完美运行大多数网站。这里的困难是找到一个在apache上安装了mod_mono的主机,或者如果你有shell访问权限,可以自己做。

    无论哪种方式,Mono都很棒,也很稳定。

    创建跨平台程序时要记住的关键事项:

    • 使用GTK#而不是Windows。形式
    • 确保文件名大小写正确
    • 使用 Path.Separator 而不是硬编码 "\" ,也使用 Environment.NewLine 而不是 "\n" .
    • 不要对Win32 API使用任何P/Invoked调用。
    • 不要使用Windows注册表。
        4
  •  23
  •   damageboy    17 年前

    我个人在黄金时段环境中使用Mono。 我运行处理千兆字节udp/tcp数据处理相关任务的mono服务器,我非常高兴。

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

    • MonoDevelop(IDE)有一些部分的msbuild支持,但基本上会在简单的hello世界之外的任何“REAL”构建conf上运行(自定义构建任务、动态“属性”如$(SolutionDir)、真实配置等等)
    • xbuild哪个 应该是 mono提供的msbuild完全兼容的构建系统甚至更可怕,因此从命令行构建实际上比使用GUI更糟糕,对于Linux环境来说,GUI是一种非常“非正统”的状态。..

    一旦/在实际构建你的东西的过程中,你可能会看到一些疯狂之处,甚至是应该支持的代码,比如:

    • 编译器在某些构造上遇到了问题
    • 以及某些更先进/新的。NET类向你抛出意想不到的垃圾(XLinq有人吗?)
    • 一些不成熟的运行时“功能”(x64上的3GB堆限制…WTF!)

    但里丁说,一般来说,事情开始得很快,解决方案/变通方法也很多 .

    一旦你克服了最初的障碍,我的经验就是单火箭,每次迭代都会变得更好 .

    我曾让服务器运行单声道,每天处理300GB的数据,处理大量的p/调用,一般来说,即使使用“前沿”单声道,也要做大量的工作并保持5-6个月的运行状态。

    希望这能有所帮助。

        5
  •  21
  •   Kris Erickson    18 年前

    对公认答案的建议现在有点过时了。

    • windows窗体的实现现在相当不错。(参见 Paint-Mono Paint.net是一个非常复杂的Windows窗体应用程序。所需要的只是一些P-Invoke和不受支持的系统调用的仿真层)。
    • 路径。结合以及路径。分隔符用于连接路径和文件名。
    • windows注册表是可以的,只要您只使用它来存储和检索应用程序中的数据(即您无法从中获取任何有关windows的信息,因为它基本上是Mono应用程序的注册表)。
        6
  •  12
  •   Diodeus - James MacFarlane    17 年前

    如果你想使用WPF,那你就倒霉了,Mono目前还没有实现它的计划。

    http://www.mono-project.com/WPF

        7
  •  9
  •   head_thrash    12 年前

    嗯,单声道很棒,但据我所知,它不稳定。它有效,但当你给单进程一个严肃的工作时,它就会出错。

    TL;DR-如果您有以下情况,请不要使用单声道:

    • 在多线程环境中使用AppDomains(程序集加载\卸载)
    • 无法维持“让它失败”的模式
    • 在流程运行过程中偶尔会遇到重载事件

    那么,事实。

    我们在RHEL5、Ubuntu上使用mono-2.6.7(.net v 3.5),在我看来,它是Novell构建的最稳定的版本。它在卸载AppDomains(segfaults)方面存在问题,但是,它很少失败,到目前为止,这是可以接受的(我们)。

    可以。但是,如果你想使用.net 4.0的功能,你必须切换到2.10.x或3.x版本,这就是问题开始的地方。

    与2.6.7相比,使用新版本是不可接受的。我编写了一个简单的压力测试应用程序来测试单声道安装。

    它在这里,有使用说明: https://github.com/head-thrash/stress_test_mono

    它使用线程池工作线程。Worker将dll加载到AppDomain并尝试执行一些数学工作。有些工作是多线程的,有些是单线程的。几乎所有的工作都是CPU限制的,尽管有一些从磁盘读取文件。

    结果不是很好。事实上,对于3.0.12版本:

    • sgen GC几乎立即发生故障
    • 使用boehm的mono寿命更长(2至5小时),但最终会出现segfaults

    如上所述,sgen-gc根本不起作用(从源代码单构建):

    * Assertion: should not be reached at sgen-scan-object.h:111
    
    Stacktrace:
    
    
    Native stacktrace:
    
        mono() [0x4ab0ad]
        /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x2b61ea830cb0]
        /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x2b61eaa74425]
        /lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x2b61eaa77b8b]
        mono() [0x62b49d]
        mono() [0x62b5d6]
        mono() [0x5d4f84]
        mono() [0x5cb0af]
        mono() [0x5cb2cc]
        mono() [0x5cccfd]
        mono() [0x5cd944]
        mono() [0x5d12b6]
        mono(mono_gc_collect+0x28) [0x5d16f8]
        mono(mono_domain_finalize+0x7c) [0x59fb1c]
        mono() [0x596ef0]
        mono() [0x616f13]
        mono() [0x626ee0]
        /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x2b61ea828e9a]
        /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x2b61eab31ccd]
    

    至于boehm-segfauls——例如(Ubuntu 13.04,从源代码构建的mono):

    mono: mini-amd64.c:492: amd64_patch: Assertion `0' failed.
    Stacktrace:
    at <unknown> <0xffffffff>
    at System.Collections.Generic.Dictionary`2.Init (int,System.Collections.Generic.IEqualityComparer`1<TKey>) [0x00012] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:264
    at System.Collections.Generic.Dictionary`2..ctor () [0x00006] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:222
    at System.Security.Cryptography.CryptoConfig/CryptoHandler..ctor (System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00014] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/Crypto
    Config.cs:582
    at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00013] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoCo
    nfig.cs:473
    at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
    at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
    at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
    at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
    at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
    at System.Guid.NewGuid () [0x0001e] in /home/bkmz/my/mono/mcs/class/corlib/System/Guid.cs:492
    

    或者(RHEL5,mono取自此处的rpm ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home%3A/vmas%3A/mono-centos5 )

    Assertion at mini.c:3783, condition `code' not met
    Stacktrace:
    at <unknown> <0xffffffff>
    at System.IO.StreamReader.ReadBuffer () [0x00012] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:394
    at System.IO.StreamReader.Peek () [0x00006] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:429
    at Mono.Xml.SmallXmlParser.Peek () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:271
    at Mono.Xml.SmallXmlParser.Parse (System.IO.TextReader,Mono.Xml.SmallXmlParser/IContentHandler) [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:346
    at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00021] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptog
    raphy/CryptoConfig.cs:475
    at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
    at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
    at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
    at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
    at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
    at System.Guid.NewGuid () [0x0001e] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/Guid.cs:483
    at System.Runtime.Remoting.RemotingServices.NewUri () [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:356
    at System.Runtime.Remoting.RemotingServices.Marshal (System.MarshalByRefObject,string,System.Type) [0x000ba] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:329
    at System.AppDomain.GetMarshalledDomainObjRef () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/AppDomain.cs:1363
    

    这两个失败都与AppDomains逻辑有关,因此,您应该在mono中远离它们。

    顺便说一句,测试程序在微软的Windows机器上工作了24小时。NET 4.5环境,没有任何故障。

    所以,最后,我想说——谨慎使用单声道。它从第一眼就起作用,但随时都可能失败。你会留下一堆核心转储和对开源项目的重大信任损失。

        8
  •  5
  •   Joe Shaw OscarRyz    18 年前

    正如其他人所说,现代艺术博物馆是一个很好的工具。如今,不兼容的最大来源是DllImport(或P/Invoke)到Win32库中的应用程序。有些程序集没有实现,但它们中的大多数仅适用于Windows,在Linux上真的没有意义。我认为可以相当肯定地说,大多数ASP。NET应用程序可以在Mono上运行,只需进行有限的修改。

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

        9
  •  4
  •   TheSmurf    18 年前

    在许多情况下,您可以使用现有代码并在Mono上运行它,特别是如果您要移植ASP。NET应用程序。

    在某些情况下,您可能需要全新的代码段才能使其工作。如果您使用System。窗户。例如,表单,应用程序在未经修改的情况下无法工作。同样,如果您使用任何特定于Windows的代码(例如注册表访问代码)。但我认为最糟糕的罪犯是UI代码。这在Macintosh系统上尤其糟糕。

        10
  •  4
  •   CHitchcock    18 年前

    我们一直在将它用于一个需要在Linux上运行但需要重用一些的项目。NET库,我们在托管C++中构建。我对它的效果感到非常惊讶。我们的主可执行文件是用C#编写的,我们可以毫无问题地引用我们的托管C++二进制文件。Windows和Linux之间C#代码的唯一区别是RS232串行端口代码。

    我能想到的唯一一个大问题发生在大约一个月前。Linux版本存在内存泄漏,这在Windows版本上是看不到的。在进行了一些手动调试(Linux上Mono的基本分析器没有多大帮助)后,我们能够将问题缩小到特定的代码块。我们最终修补了一个解决方法,但我仍然需要找一些时间回去找出泄漏的根本原因。

        11
  •  2
  •   jsight TaherT    18 年前

    你知道Mono 2.0预览版对Windows Forms 2.0的支持有多好吗?

    从我玩过的一点点来看,它似乎相对完整,几乎可以使用。它只是在某些地方看起来不太对劲,总体上仍然有点受欢迎或不受欢迎。让我惊讶的是,它和我们的一些表格一样有效,尽管说实话。

        12
  •  2
  •   Thomas Hansen    17 年前

    是的,确实如此(但如果你小心的话) 我们支持Ra Ajax中的Mono(Ajax库位于 http://ra-ajax.org )我们基本上没有任何问题。你需要小心一些“最疯狂的事情”。Net类WSE等,也可能有相当多的现有项目不会100%兼容Mono,但如果你在开发过程中测试新项目,它们大多会兼容Mono,不会出现问题。通过使用Mono支持Linux等带来的好处真的很酷;)

    我认为支持Mono的很大一部分秘诀是从一开始就使用正确的工具,例如ActiveRecord、log4net、ra-ajax等。。。

        13
  •  2
  •   Alex Black    17 年前

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

    错误消息是:“GC中的致命错误:堆段太多”,这里有一个链接,指向其他以稍微不同的方式遇到问题的人:

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

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

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

    这段代码非常简单,例如,将一些数据放入HashSets,然后查询这些HashSets等,所有原生c#,没有不安全的,没有API调用。在Microsoft CLR上,它永远不会崩溃,并且可以在巨大的数据集上运行1000次。

    我们的一个人给Miguel发了电子邮件,并附上了导致问题的代码,但还没有得到回应。 :(

    似乎许多其他人在没有解决方案的情况下也遇到了这个问题——有人建议用不同的GC设置重新编译Mono,但这似乎只是增加了它崩溃的阈值。

        14
  •  2
  •   Pablo    17 年前

    只需查看www.plasticscm.com。所有内容(客户端、服务器、GUI、合并工具)都是在mono上编写的。

        15
  •  1
  •   Eric Z Beard    18 年前

    这实际上取决于您从中使用的命名空间和类。NET框架。我有兴趣将我的一个windows服务转换为在我的电子邮件服务器Suse上运行,但我们遇到了几个尚未完全实现的API的困难。Mono网站上有一张图表,列出了所有课程及其完成程度。如果你的申请有保障,那就去申请吧。

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

    我们遇到的另一个问题是许可软件:如果你引用了别人的DLL,你就无法绕过该程序集中隐藏的不兼容问题。

        16
  •  1
  •   Jamie    18 年前

    我可以想象,如果你有一个包含一些第三方组件的应用程序,你可能会被塞满。我怀疑很多供应商在开发时都不会考虑Mono

    例子: http://community.devexpress.com/forums/p/55085/185853.aspx

        17
  •  1
  •   Stefan    16 年前

    不,mono还没有准备好进行认真的工作。我使用F#在Windows上编写了一些程序,并在mono上运行了它们。这些程序相当密集地使用磁盘、内存和cpu。我看到mono库(托管代码)崩溃、本机代码崩溃和虚拟机崩溃。当单声道工作时,程序至少比中慢两倍。Windows中的网络,占用了更多的内存。认真工作时远离单声道。

    推荐文章