有人在大型或中型项目中使用过。net开源实现Mono吗?我想知道它是否已经为现实世界的生产环境做好了准备。它是否稳定、快速、兼容……足够用了吗?将项目移植到Mono运行时是否需要花费大量的精力,或者它是否真的足够兼容,只需要为微软的运行时编写代码就可以了?
当前回答
我可以想象,如果你有一个带有一些第三方组件的应用程序,你可能会被塞满。我怀疑很多供应商会在开发过程中考虑到Mono
例如:http://community.devexpress.com/forums/p/55085/185853.aspx
其他回答
MoMA是一个很好的工具,就像其他人建议的那样。目前最大的不兼容性来源是将DllImport(或P/Invoke)导入Win32库的应用程序。有些程序集没有实现,但大多数程序集仅适用于windows,在Linux上确实没有意义。我认为可以肯定地说,大多数ASP。NET应用程序可以在Mono上运行,只需进行有限的修改。
(披露:我为Mono本身做出了贡献,也编写了在Mono上运行的应用程序。)
不,单核细胞增多症还不能胜任严肃的工作。我用f#在Windows上写了几个程序,然后在Mono上运行。这些程序相当密集地使用磁盘、内存和cpu。我看到在单库(托管代码)中崩溃,在本地代码中崩溃,在虚拟机中崩溃。当mono运行时,程序比Windows中的。net慢了至少两倍,并且占用了更多的内存。在严肃的工作中远离单核细胞增多症。
单核细胞增多症很好,但据我所知,它不稳定。它可以工作,但是当你给单一进程一个严肃的工作去做时,它就会出错。
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相比,新版本简直无法接受。我编写了一个简单的压力测试应用程序来测试mono安装。
它在这里,并附有使用说明:https://github.com/head-thrash/stress_test_mono
它使用线程池工作线程。Worker将dll加载到AppDomain并尝试做一些数学工作。有些工作是多线程的,有些是单线程的。几乎所有的工作都是cpu限制的,尽管有一些从磁盘读取文件。
结果不是很好。事实上,对于3.0.12版本:
sgen GC段错误几乎立即处理 带有boehm的Mono存活时间更长(从2到5小时),但最终会出现段故障
如上所述,sgen gc不能工作(mono从源代码构建):
* 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 segfaults -例如(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小时,在MS . net 4.5环境下没有任何故障。
总之,我想说的是,谨慎使用单倍体。它从第一眼就能起作用,但无论何时都很容易失败。你会留下一堆核心转储和对开源项目的重大信心损失。
在许多情况下,你可以获取现有的代码并在Mono上运行,特别是如果你正在移植一个ASP。网络应用程序。
在某些情况下,您可能需要全新的代码段才能使其工作。如果你使用System.Windows。例如,如果不修改表单,应用程序将无法工作。同样,如果您使用任何特定于windows的代码(例如,注册表访问代码)。但我认为最糟糕的是UI代码。这在麦金塔系统上尤其糟糕。
对于公认答案的建议现在有点过时了。
The windows forms implementation is pretty good now. (See Paint-Mono for a port of Paint.net which is a pretty involved Windows forms application. All that was required was an emulation layer for some of the P-Invoke and unsupported system calls). Path.Combine as well as Path.Seperator to join paths and filenames. The windows Registry is OK, as long as you are only using it for storing and retrieving data from your applications (i.e. you can't get any information about Windows from it, since it is basically a registry for Mono applications).
推荐文章
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- AppSettings从.config文件中获取值
- 如何检查IEnumerable是否为空或空?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 如何在iis7应用程序池中设置。net Framework 4.5版本
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何指定最小值,但没有使用范围数据注释属性的最大小数?
- 如何在PowerShell中获得本地主机名?
- 为什么在Java和。net中不能修改字符串?
- 'throw'和'throw new Exception()'的区别
- c# int到字节[]
- 如何跟踪log4net问题
- foreach vs somlist . foreach (){}