update net downloads compilador caracteristicas .net open-source mono

.net - net - monodevelop



¿Está listo Mono para el prime time? (17)

¿Alguien ha utilizado Mono, la implementación de .NET de código abierto en un proyecto grande o mediano? Me pregunto si está listo para el mundo real, entornos de producción. ¿Es estable, rápido, compatible, ... suficiente para usar? ¿Se requiere mucho esfuerzo para portar proyectos al tiempo de ejecución de Mono, o es realmente lo suficientemente compatible como para tomar y ejecutar código ya escrito para el tiempo de ejecución de Microsoft?


¿Sabes lo bueno que es el soporte de Mono 2.0 preview para Windows Forms 2.0?

Por lo poco que he jugado con él, parecía relativamente completo y casi utilizable. Simplemente no se veía bien en algunos lugares y aún es un poco impredecible en general. Me sorprendió que funcionara tan bien como lo hizo con algunas de nuestras formas, aunque honestamente.


Bueno, el mono es genial, pero por lo que puedo ver, es inestable. Funciona, pero las fallas cuando le das al proceso mono un trabajo serio que hacer.

TL; DR: no uses mono si:

  • use AppDomains (Assembly Load / Unload) en entornos multiproceso
  • No se puede sostener el modelo ''dejarlo fallar''
  • Experimente eventos ocasionales de carga pesada durante la ejecución del proceso

Entonces, los hechos.

Utilizamos mono-2.6.7 (.net v 3.5) en RHEL5, Ubuntu y, en mi opinión, es la versión más estable construida por Novell. Tiene un problema con Unloading AppDomains (segfaults), sin embargo, falla muy raramente y esto, de lejos, es aceptable (por nosotros).

Bueno. Pero si desea usar las características de .net 4.0, tiene que cambiar a las versiones 2.10.x, o 3.x, y ahí es donde comienzan los problemas.

En comparación con 2.6.7, las nuevas versiones son inaceptables de usar. Escribí una sencilla aplicación de prueba de estrés para probar instalaciones mono.

Es aquí, con instrucciones para usar: https://github.com/head-thrash/stress_test_mono

Utiliza hilos Thread Pool Worker. Worker carga dll en AppDomain e intenta hacer un poco de trabajo matemático. Algunos de los trabajos tienen muchos hilos, otros son solteros. Casi todo el trabajo está vinculado a la CPU, aunque hay algunas lecturas de archivos del disco.

Los resultados no son muy buenos. De hecho, para la versión 3.0.12:

  • sgen GC segfaults procesa casi inmediatamente
  • mono con boehm vive más tiempo (de 2 a 5 horas), pero eventualmente las segregaciones

Como se mencionó anteriormente, sgen gc simplemente no funciona (mono construido desde la fuente):

* 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]

En cuanto a boehm segfauls, por ejemplo (Ubuntu 13.04, mono construido desde la fuente):

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

O (RHEL5, mono se toma de rpm aquí 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

Ambas fallas están conectadas de alguna manera a la lógica de AppDomains, por lo tanto, debe mantenerse alejado de ellas en mono.

Por cierto, el programa probado funcionó las 24 horas en la máquina Windows en MS .NET 4.5 env sin ningún fallo.

Así que, en conclusión, me gustaría decir: use mono con precaución. Funciona desde el primer vistazo, pero puede fallar fácilmente siempre que sea. Te quedarían con un montón de volcados de datos y una gran pérdida de fe en proyectos de código abierto.


En el lado del escritorio, Mono funciona muy bien si te comprometes a usar GTK #. La implementación de Windows.Forms es todavía un poco defectuosa (por ejemplo, TrayIcon no funciona) pero ha recorrido un largo camino. Además, GTK # es un mejor kit de herramientas que Windows Forms.

En el lado web, Mono ha implementado suficiente ASP.NET para ejecutar la mayoría de los sitios a la perfección. La dificultad aquí es encontrar un host que tenga mod_mono instalado en apache, o hacerlo usted mismo si tiene acceso de shell a su host.

De cualquier manera, Mono es genial, y estable.

Cosas clave para recordar al crear un programa multiplataforma:

  • Use GTK # en lugar de Windows.Forms
  • Asegúrate de incluir correctamente tus nombres de archivo
  • Use Path.Separator lugar de hardcoding "/" , también use Environment.NewLine lugar de "/n" .
  • No utilice ninguna llamada P / Invoked a la API de Win32.
  • No utilice el registro de Windows.

En muchos casos, puede tomar el código existente y simplemente ejecutarlo en Mono, particularmente si está portando una aplicación ASP.NET.

En algunos casos, es posible que necesite nuevas secciones de código para que funcione. Si utiliza System.Windows.Forms, por ejemplo, la aplicación no funcionará sin modificaciones. Del mismo modo, si utiliza cualquier código específico de Windows (código de acceso al registro, por ejemplo). Pero creo que el peor infractor es el código UI. Eso es particularmente malo en los sistemas Macintosh.


Hay un par de escenarios a considerar: (a) si está portando una aplicación existente y se pregunta si Mono es lo suficientemente bueno para esta tarea; (b) estás empezando a escribir un código nuevo y quieres saber si Mono es lo suficientemente maduro.

Para el primer caso, puede usar la herramienta Mono Migration Analyzer (Moma) para evaluar qué tan lejos está su aplicación de ejecutarse en Mono. Si la evaluación regresa con éxito, debe comenzar con sus pruebas y control de calidad y prepararse para el envío.

Si su evaluación vuelve con un informe que resalta las características que faltan o difieren significativamente en su semántica en Mono, tendrá que evaluar si el código puede adaptarse, reescribirse o, en el peor de los casos, si su aplicación puede funcionar con funcionalidad reducida.

Según nuestras estadísticas de Moma basadas en las presentaciones de los usuarios (esto es de memoria), aproximadamente el 50% de las aplicaciones funcionan de forma inmediata, aproximadamente el 25% requiere aproximadamente una semana de trabajo (refactorización, adaptación), otro 15% requiere un compromiso serio con Rehaga fragmentos de su código, y el resto simplemente no vale la pena molestarse en portar ya que están increíblemente ligados a Win32. En ese momento, ya sea que comience desde cero, o una decisión comercial impulsará el esfuerzo de hacer que su código sea portátil, pero estamos hablando de meses de trabajo (al menos de los informes que tenemos).

Si está empezando de cero, la situación es mucho más sencilla, ya que solo usará las API que están presentes en Mono. Mientras permanezca con la pila compatible (que es prácticamente .NET 2.0, más todas las actualizaciones básicas en 3.5, incluidas LINQ y System.Core, más cualquiera de las API multiplataforma de Mono) estará bien.

De vez en cuando puedes encontrar errores en Mono o limitaciones, y es posible que tengas que solucionarlos, pero eso no es diferente a ningún otro sistema.

En cuanto a la portabilidad: las aplicaciones ASP.NET son las más fáciles de portar, ya que tienen poca o ninguna dependencia en Win32 e incluso puede usar el servidor SQL u otras bases de datos populares (hay muchos proveedores de bases de datos empaquetadas con Mono).

La migración de Windows.Forms es a veces más complicada porque a los desarrolladores les gusta escapar del arenero .NET y P / Invoke sus cerebros para configurar cosas tan útiles como cambiar la velocidad de parpadeo del cursor expresada como dos puntos bezier codificados en forma BCD en un wParam. O alguna basura como esa.


Las recomendaciones para la respuesta aceptada están un poco desactualizadas.

  • La implementación de Windows Forms es bastante buena ahora. (Consulte Paint-Mono para un puerto de Paint.net que es una aplicación de formularios de Windows bastante complicada. Todo lo que se requería era una capa de emulación para algunas de las llamadas de P-Invoke y del sistema no compatible).
  • Path.Combine y Path.Seperator para unir rutas y nombres de archivos.
  • El Registro de Windows está bien, siempre y cuando solo lo esté utilizando para almacenar y recuperar datos de sus aplicaciones (es decir, no puede obtener ninguna información sobre Windows, ya que es básicamente un registro para aplicaciones Mono).

Lo hemos estado usando para un proyecto aquí en el trabajo que necesitaba para ejecutarse en Linux pero reutilizar algunas bibliotecas .NET que construimos en Managed C ++. Me ha sorprendido lo bien que ha funcionado. Nuestro ejecutable principal se escribe en C # y solo podemos hacer referencia a nuestros binarios de C ++ administrado sin problemas. La única diferencia en el código C # entre Windows y Linux es el código de puerto serie RS232.

El único gran problema que se me ocurre ocurrió hace un mes. La compilación de Linux tenía una pérdida de memoria que no se había visto en la compilación de Windows. Después de realizar una depuración manual (los perfiladores básicos para Mono en Linux no ayudaron mucho), pudimos reducir el problema a un fragmento específico de código. Terminamos parcheando una solución alternativa, pero aún tengo que encontrar algo de tiempo para volver y averiguar cuál fue la causa principal de la fuga.



MoMA es una gran herramienta para esto, como sugirió otra persona. Las mayores fuentes de incompatibilidad en estos días son las aplicaciones que DllImport (o P / Invoke) en las bibliotecas de Win32. Algunos ensamblados no están implementados, pero la mayoría de ellos son solo para Windows y realmente no tendrían sentido en Linux. Creo que es bastante seguro decir que la mayoría de las aplicaciones ASP.NET pueden ejecutarse en Mono con modificaciones limitadas.

(Revelación: he contribuido con Mono en sí, así como con aplicaciones escritas que se ejecutan sobre él).


No, mono no está listo para un trabajo serio. Escribí algunos programas en Windows usando F # y los ejecuté en Mono. Esos programas utilizaban disco, memoria y cpu bastante intensivamente. Vi fallos en bibliotecas mono (código administrado), fallos en código nativo y fallos en la máquina virtual. Cuando mono funcionaba, los programas eran al menos dos veces más lentos que en .Net en Windows y usaban mucha más memoria. Manténgase alejado de mono para el trabajo serio.


Para el tipo de aplicación que estamos construyendo, desafortunadamente, Mono no parece estar listo para la producción. En general, nos impresionó y nos impresionó su rendimiento tanto en Windows como en las máquinas EC2; sin embargo, nuestro programa se bloqueó consistentemente con errores de recolección de basura en Windows y Linux.

El mensaje de error es: "errores fatales en GC: demasiadas secciones del montón", aquí hay un enlace a otra persona que experimenta el problema de una manera ligeramente diferente:

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

El primer fragmento de código que ejecutamos en Mono fue un simple desafío de programación que habíamos desarrollado ... El código carga datos de aproximadamente 10 mb en algunas estructuras de datos (por ejemplo, HashSets), y luego ejecuta 10 consultas contra los datos. Realizamos las consultas 100 veces para cronometrarlas y obtener un promedio.

El código se bloqueó alrededor de la consulta 55 en Windows. En Linux funcionó, pero tan pronto como nos moviéramos a un conjunto de datos más grande, también se bloquearía.

Este código es muy simple, por ejemplo, ponga algunos datos en HashSets y luego consulte esos HashSets, etc., todos los C # nativos, nada inseguro, no llamadas API. En el Microsoft CLR nunca se bloquea, y se ejecuta en grandes conjuntos de datos 1000 veces bien.

Uno de nuestros chicos le envió un correo electrónico a Miguel e incluyó el código que causó el problema, aún no hay respuesta. :(

También parece que muchas otras personas han encontrado este problema sin una solución: se ha sugerido una solución para recompilar Mono con diferentes configuraciones de GC, pero eso parece aumentar el umbral antes de que se bloquee.


Personalmente uso Mono en un env de prime time. Ejecuto servidores mono que tratan con giga-bytes de tareas relacionadas con el procesamiento de datos udp / tcp y no podría ser más feliz.

Hay peculiaridades, y una de las cosas más molestas es que no puedes simplemente "construir" tus archivos msbuild debido al estado actual de Mono:

  • MonoDevelop (el IDE) tiene un soporte parcial de msbuild, pero básicamente funciona con cualquier configuración de configuración "REAL" más allá de un simple hello-mundo (tareas de creación personalizadas, "propiedades" dinámicas como $ (SolutionDir), configuración real para nombrar algunos muertos) -los fines
  • xbuild, que DEBERÍA haber sido el sistema de compilación mono-suministrado-msbubleado-totalmente compatible, es aún más horrible, por lo que construir desde la línea de comandos es en realidad una experiencia peor que usar la GUI, que es un estado muy "poco ortodoxo" del Unión para entornos Linux ...

Una vez / durante la compra de tus cosas, puedes ver algunas áreas desiertas incluso para el código que DEBERÍA ser compatible como:

  • El compilador está siendo borked en ciertas construcciones
  • y ciertas clases de .NET más avanzadas / nuevas que te lanzan una basura inesperada (¿XLinq alguien?)
  • algunas "características" de tiempo de ejecución inmaduras (límite de almacenamiento dinámico de 3GB en x64 ... WTF!)

pero abultado dijo que, en general, las cosas comienzan a funcionar muy rápidamente y que las soluciones / soluciones son abundantes .

Una vez que has superado esos obstáculos iniciales, mi experiencia es que ROCKS mono, y sigue mejorando con cada iteración .

He tenido servidores que funcionan con mono, que procesan 300 GB de datos por día, con toneladas de invocaciones / invocaciones y, en general, hacen MUCHO trabajo y permanecen despiertos durante 5 a 6 meses, incluso con el mono "de vanguardia".

Espero que esto ayude.


Realmente depende de los espacios de nombres y las clases que está utilizando desde el marco .NET. Tenía interés en convertir uno de mis servicios de Windows para que se ejecutara en mi servidor de correo electrónico, que es Suse, pero nos topamos con varios obstáculos difíciles con API que no se habían implementado por completo. Hay un cuadro en alguna parte del sitio web de Mono que enumera todas las clases y su nivel de finalización. Si su aplicación está cubierta, entonces vaya por ella.

Como cualquier otra aplicación, haga prototipos y pruebas antes de comprometerse por completo, por supuesto.

Otro problema con el que nos encontramos es el software con licencia: si estás haciendo referencia a la DLL de otra persona, no puedes codificar las incompatibilidades que están ocultas en ese ensamblaje.


Sí, definitivamente lo es (aunque sea cuidadoso). Apoyamos a Mono en Ra-Ajax (biblioteca de Ajax que se encuentra en http://ra-ajax.org ) y, en su mayoría, no tenemos ningún problema. Debe tener cuidado con algunas de las "cosas más insensatas" de .Net como WSE, etc., y probablemente algunos de sus proyectos existentes no serán 100% Mono compatibles, pero los proyectos nuevos si los prueba durante el desarrollo serán principalmente Ser compatible sin problemas con Mono. Y la ganancia de soportar Linux, etc. mediante el uso de Mono es realmente genial;)

Creo que una gran parte del secreto del soporte de Mono es utilizar las herramientas adecuadas desde el principio, por ejemplo, ActiveRecord, log4net, ra-ajax, etc.


Sólo tienes que consultar www.plasticscm.com. Todo (cliente, servidor, GUI, herramientas de combinación) está escrito en mono.



Tiene una cobertura bastante extensa hasta .NET 4.0 e incluso incluye algunas características de las API .NET 4.5, pero hay algunas áreas que hemos elegido no implementar debido a que las API están en desuso, se están creando nuevas alternativas o el alcance también. grande. Las siguientes API no están disponibles en Mono:

  • Fundación de presentación de Windows
  • Windows Workflow Foundation (ninguna de las dos versiones)
  • Marco de la entidad
  • Los "complementos" WSE1 / WSE2 a la pila de servicios web estándar

Además, nuestra implementación de WCF se limita a lo que Silverlight admite.

La forma más fácil de verificar su proyecto específico es ejecutar Mono Migration Analyzer (MoMA) . El beneficio es que notificará al equipo de Mono los problemas que le impedirán utilizar Mono (si corresponde), lo que les permite priorizar su trabajo.

Recientemente ejecuté MoMA en SubSonic y encontré un solo problema: un uso extraño de los tipos de Nullable. Eso es una gran base de código, por lo que la cobertura fue bastante impresionante.

Mono está en uso activo en varios productos comerciales y de código abierto . Se utiliza en algunas aplicaciones grandes, como Wikipedia y el Centro de desarrolladores de Mozilla , y se ha utilizado en aplicaciones integradas como los reproductores de MP3 Sansa y potencia miles de juegos publicados.

En el nivel de idioma, el compilador Mono es totalmente compatible con la especificación de lenguaje C # 5.0 .