Готово ли Mono в прайм-тайм?

Кто-нибудь использовал Mono, реализацию .NET с открытым исходным кодом на крупном или среднем проекте? Мне интересно, готов ли он к реальному миру, производственной среде. Является ли он стабильным, быстрым, совместимым,... достаточным для использования? Требуется ли много усилий для переноса проектов в среду выполнения Mono или действительно ли это действительно достаточно для того, чтобы просто взять и запустить уже написанный код для среды выполнения Microsoft?

Ответ 1

Есть несколько сценариев, которые следует учитывать: (a) если вы переносите существующее приложение и задаетесь вопросом, достаточно ли Mono для этой задачи; (b) вы начинаете писать какой-то новый код, и хотите узнать, достаточно ли зрелости Mono.

В первом случае вы можете использовать Средство анализа мозаики (Moma), чтобы оценить, насколько далеко ваше приложение работает в Mono. Если оценка вернется с летающими цветами, вы должны начать с тестирования и QA и подготовиться к отправке.

Если ваша оценка вернется с отчетом, в котором выделяются функции, которые отсутствуют или значительно отличаются по своей семантике в Mono, вам придется оценить, может ли код быть адаптирован, переписан или в худшем случае может ли ваше приложение работать со сниженной функциональностью,

Согласно нашей статистике Moma, основанной на пользовательских представлениях (это из памяти), около 50% приложений работают из коробки, около 25% требуют около недели работы (рефакторинг, адаптация), еще 15% требуют серьезное обязательство повторить куски вашего кода, а остальное просто не стоит беспокоить портирование, так как они настолько невероятно привязаны к Win32. В этот момент вы начинаете с нуля или бизнес-решение будет стимулировать работу вашего портативного компьютера, но мы говорим о месячной работе (по крайней мере, из отчетов, которые у нас есть).

Если вы начинаете с нуля, ситуация намного проще, потому что вы будете использовать только API, которые присутствуют в Mono. До тех пор, пока вы останетесь с поддерживаемым стеком (это в значительной степени .NET 2.0, плюс все основные обновления в 3.5, включая LINQ и System.Core, плюс любой из кросс-платформенных API Mono), вы будете в порядке.

Время от времени вы можете столкнуться с ошибками в Mono или ограничениями, и вам, возможно, придется обойти их, но это не отличается от любой другой системы.

Что касается переносимости: приложения ASP.NET легче переносить, поскольку у них практически нет зависимостей с Win32, и вы даже можете использовать SQL-сервер или другие популярные базы данных (в комплекте есть много поставщиков баз данных с Mono).

Портирование Windows.Forms иногда бывает сложнее, потому что разработчикам нравится избегать песочницы .NET и P/Invoke их мозги, чтобы настроить вещи так же полезно, как изменение скорости мигания курсора, выраженное в виде двух безьевых точек, закодированных в форме BCD, в wParam, Или какой-то хлам вроде этого.

Ответ 2

Он имеет довольно обширное покрытие до .NET 4.0 и даже включает некоторые функции из API.NET 4.5, но есть несколько областей, которые мы выбрали не для реализации из-за устаревших API, создания новых альтернатив или масштаб слишком велик. Следующие API не доступны в Mono:

  • Windows Presentation Foundation
  • Windows Workflow Foundation (ни одна из двух версий)
  • Entity Framework
  • "Дополнения WSE1/WSE2" к стандартным стекам веб-служб

Кроме того, наша реализация WCF ограничена поддержкой Silverlight.

Самый простой способ проверить ваш конкретный проект - запустить Mono Migration Analyzer (MoMA). Преимущество состоит в том, что он будет уведомлять группу Mono о проблемах, которые помешают вам использовать Mono (если есть), что позволяет им расставлять приоритеты в своей работе.

Недавно я запустил MoMA на SubSonic и нашел только одну проблему - странное использование типов Nullable. Это большая база кода, поэтому охват там был довольно впечатляющим.

Моно активно используется в нескольких коммерческих, а также с открытым исходным кодом. Он используется в некоторых крупных приложениях, таких как Википедия и Центр разработчиков Mozilla и используется во встроенных приложениях, таких как MP3-плееры Sansa и тысячи тысяч опубликованных игр.

На уровне языка компилятор Mono полностью соответствует спецификации языка С# 5.0.

Ответ 3

На рабочем столе Mono отлично работает, если вы обязуетесь использовать GTK #. Реализация Windows.Forms по-прежнему немного ошибочна (например, TrayIcon не работает), но она прошла долгий путь. Кроме того, GTK # - лучший инструментарий, чем Windows Forms, как есть.

На веб-странице Mono реализовала достаточно ASP.NET для запуска большинства сайтов. Трудность здесь заключается в поиске хоста, на котором установлен mod_mono на apache, или его самого, если у вас есть доступ к оболочке на ваш хост.

В любом случае, Моно здорово и стабильно.

Ключевые моменты, которые следует помнить при создании кросс-платформенной программы:

  • Используйте GTK # вместо Windows.Forms
  • Убедитесь, что вы правильно указали свои имена файлов
  • Используйте Path.Separator вместо hardcoding "\", также используйте Environment.NewLine вместо "\n".
  • Не используйте вызовы P/Invoked для Win32 API.
  • Не используйте реестр Windows.

Ответ 4

Я лично использую Mono в прайм-тайм env. Я запускаю mono-серверы, которые работают с giga-байтами задач обработки данных udp/tcp и не могут быть более счастливыми.

Есть особенности, и одна из самых неприятных вещей заключается в том, что вы не можете просто "создавать" ваши файлы msbuild из-за текущего состояния Mono:

  • MonoDevelop (IDE) имеет некоторую частичную поддержку msbuild, но в основном будет работать над любой версией REAL, созданной за пределами простого приветствия (задачи пользовательской сборки, динамические "свойства", такие как $(SolutionDir), реальная конфигурация, чтобы назвать несколько тупиков)
  • xbuild, который ДОЛЖЕН быть монопольной-msbuild-полностью совместимой-build-системой, еще более ужасен, поэтому построение из командной строки на самом деле хуже, чем использование графического интерфейса, что является очень "неортодоксальным", состояние объединения для сред Linux...

Как только/Во время получения вашего материала на самом деле ПОСТРОЕН, вы можете увидеть некоторые глушители даже для кода, который ДОЛЖЕН поддерживаться, например:

  • компилятор, связанный с определенными конструкциями
  • и некоторые более продвинутые/новые классы .NET, бросающие ненужное дерьмо на вас (XLinq кто-нибудь?)
  • некоторые незрелые функции времени исполнения (ограничение 3 кучи 3 ГБ на x64... WTF!)

но heaving сказал, что в целом вещи начинают работать очень быстро, а решения/обходные пути в изобилии.

Как только вы преодолеете эти начальные препятствия, мой опыт в том, что mono ROCKS и продолжает улучшаться с каждой итерацией.

У меня были серверы, работающие с моно, обрабатывающие 300 ГБ данных в день, с тоннами p/invokes и, вообще говоря, работая над LOTS и оставаясь UP в течение 5-6 месяцев, даже с монофоном "bleeding edge".

Надеюсь, что это поможет.

Ответ 5

Рекомендации для принятого ответа немного устарели.

  • Реализация окон очень хороша. (См. Paint-Mono для порта Paint.net, который представляет собой довольно активное приложение форм Windows. Все, что требовалось, было слоем эмуляции для некоторых системных вызовов P-Invoke и неподдерживаемых систем).
  • Path.Combine, а также Path.Seperator для объединения путей и имен файлов.
  • Реестр Windows в порядке, если вы используете его только для хранения и извлечения данных из ваших приложений (т.е. вы не можете получить от него какую-либо информацию о Windows, поскольку это, в основном, реестр для приложений Mono).

Ответ 6

Если вы хотите использовать WPF, вы не повезло. Моно в настоящее время не планирует его реализовывать.

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

Ответ 7

Ну, mono отлично, но, насколько я вижу, он неустойчив. Это работает, но ошибки, когда вы даете моно-процессу серьезную работу.

TL; DR - Не используйте моно, если вы:

  • использовать AppDomains (сборка\выгрузка) в многопоточных средах
  • Не удается выдержать модель "let-it-fail".
  • Опыт случайных событий большой нагрузки во время процесса

Итак, факты.

Мы используем mono-2.6.7 (.net v 3.5) на RHEL5, Ubuntu, и, с моей точки зрения, это самая стабильная версия, построенная Novell. У этого есть проблема с Разгрузкой AppDomains (segfaults), однако, это терпит неудачу очень редко, и это, безусловно, приемлемо (нами).

Хорошо. Но если вы хотите использовать функции .net 4.0, вам нужно переключиться на версии 2.10.x или 3.x и начать там проблемы.

По сравнению с 2.6.7, новые версии просто неприемлемы для использования. Я написал простое приложение для стресс-теста для тестирования моноустановок.

Здесь, с инструкциями по использованию: https://github.com/head-thrash/stress_test_mono

Он использует потоки рабочих потоков пула. Рабочий загружает dll в AppDomain и пытается выполнить некоторую математическую работу. Некоторая работа многопоточная, некоторые - одиночные. Почти вся работа связана с процессором, хотя есть некоторые чтения файлов с диска.

Результаты не очень хорошие. На самом деле, для версии 3.0.12:

  • sgen GC segfaults процесс почти мгновенно
  • mono с boehm живет дольше (от 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]

Что касается behm segfauls - например (Ubuntu 13.04, моно построенный из источника):

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, поэтому вы должны держаться подальше от них в моно.

BTW, проверенная программа работала 24 часа на машине Windows в MS.NET 4.5 env без каких-либо сбоев.

Итак, в заключение, я хотел бы сказать - используйте моно с осторожностью. Он работает с первого взгляда, но может легко сработать всякий раз. У вас останется куча основных дампов и большая потеря веры в проектах с открытым исходным кодом.

Ответ 8

MoMA - отличный инструмент для этого, как и кто-то другой. В наши дни самыми большими источниками несовместимости являются приложения, которые DllImport (или P/Invoke) в библиотеки Win32. Некоторые сборки не реализованы, но большинство из них только для Windows и действительно не имеет смысла в Linux. Я думаю, что достаточно безопасно сказать, что большинство приложений ASP.NET могут работать в Mono с ограниченными модификациями.

(Раскрытие: я внес вклад в Mono, а также написанные приложения, которые работают поверх него.)

Ответ 9

Во многих случаях вы можете взять существующий код и просто запустить его в Mono, особенно если вы портируете приложение ASP.NET.

В некоторых случаях вам могут потребоваться целые новые разделы кода, чтобы они работали. Например, если вы используете System.Windows.Forms, приложение не будет работать без изменений. Аналогично, если вы используете какой-либо код для Windows (например, код доступа к реестру). Но я считаю, что худшим нарушителем является код пользовательского интерфейса. Это особенно плохо для систем Macintosh.

Ответ 10

Мы использовали его для проекта здесь, на работе, который необходимо запустить в Linux, но повторно использовать некоторые библиотеки .NET, которые мы создали в Managed С++. Я очень удивился тому, как хорошо это получилось. Наш основной исполняемый файл написан на С#, и мы можем просто ссылаться на наши управляемые С++ файлы без проблем. Единственное отличие в коде С# между Windows и Linux - это код последовательного порта RS232.

Единственная серьезная проблема, о которой я могу думать, произошла примерно месяц назад. В сборке Linux произошла утечка памяти, которая не была видна в сборке Windows. После некоторой ручной отладки (базовые профилировщики для Mono on Linux не очень помогли), мы смогли сузить проблему до определенного фрагмента кода. Мы закончили тем, что исправляем обходной путь, но мне все же нужно найти некоторое время, чтобы вернуться и выяснить, в чем была основная причина утечки.

Ответ 11

Знаете ли вы, насколько хороша поддержка предварительного просмотра Mono 2.0 для Windows Forms 2.0?

Из небольшого числа, что я играл с ним, он казался относительно полным и почти годным к употреблению. В некоторых местах это выглядело не совсем корректно, и в целом все еще немного ударил или промахнулся. Меня поразило, что он работал так же хорошо, как и с некоторыми из наших форм, хотя и честно.

Ответ 12

Да, это определенно (если вы осторожны) Мы поддерживаем Mono в Ra-Ajax (библиотека Ajax, найденная в http://ra-ajax.org), и у нас в основном нет проблем вообще. Вы должны быть осторожны с некоторыми из "самых безумных вещей" от .Net, таких как WSE и т.д., А также, вероятно, некоторые из ваших существующих проектов не будут совместимы с Mono на 100%, но новые проекты, если вы их тестируете во время разработки, будут в основном быть совместимым без проблем с Mono. И выигрыш от поддержки Linux и т.д. С помощью Mono действительно классный;)

Большая часть тайны поддержки Mono, я думаю, состоит в том, чтобы использовать правильные инструменты с самого начала, например. ActiveRecord, log4net, ra-ajax и т.д.

Ответ 13

Для типа приложения, которое мы создаем, Mono, к сожалению, не кажется готовым к выпуску. Мы впечатлили его в целом и впечатлили его производительность как на Windows, так и на компьютерах EC2, однако наша программа постоянно зависала с ошибками сбора мусора как на Windows, так и на Linux.

Сообщение об ошибке: "Неустранимая ошибка в GC: слишком много секций кучи", вот ссылка на кого-то другого, испытывающего проблему несколько иначе:

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

Первая часть кода, который мы запускали в Mono, была простой задачей программирования, которую мы разработали... Код загружает около 10 МБ данных в некоторые структуры данных (например, HashSets), а затем запускает 10 запросов к данным. Мы запускали запросы 100 раз, чтобы время их и получить в среднем.

Код разбился вокруг 55-го запроса в Windows. На linux это сработало, но как только мы перешли к большему набору данных, он тоже рухнет.

Этот код очень прост, например. поместить некоторые данные в HashSets, а затем запросить эти HashSets и т.д., все родные С#, ничего небезопасного, никаких вызовов API. В Microsoft CLR он никогда не сбой, и работает на огромных наборах данных в 1000 раз просто отлично.

Один из наших ребят отправил по электронной почте Miguel и включил код, вызвавший эту проблему, ответа еще не было.: (

Похоже, что многие другие люди столкнулись с этой проблемой без решения - было предложено перекомпилировать Mono с различными настройками GC, но это просто увеличивает порог, перед которым он падает.

Ответ 14

Просто проверьте www.plasticscm.com. Все (клиент, сервер, графический интерфейс, инструменты слияния) записывается на моно.

Ответ 15

Это действительно зависит от пространств имен и классов, которые вы используете из платформы .NET. У меня был интерес к конвертации одной из моих служб Windows для работы на моем почтовом сервере, который является Suse, но мы столкнулись с несколькими жесткими препятствиями с API, которые не были полностью реализованы. На веб-сайте Mono есть диаграмма, в которой перечислены все классы и уровень их завершения. Если ваше приложение закрыто, перейдите к нему.

Как и любое другое приложение, сделайте прототипирование и тестирование, прежде чем выполнять все обязательства, конечно.

Еще одна проблема, с которой мы столкнулись, - это лицензионное программное обеспечение: если вы ссылаетесь на какую-либо другую DLL-версию, вы не можете закодировать свой путь вокруг несовместимости, которая похоронена в этой сборке.

Ответ 16

Я бы предположил, что если у вас есть приложение с некоторыми сторонними компонентами, вы можете быть набиты. Я сомневаюсь, что многие производители будут развиваться с Mono в виду

Пример: http://community.devexpress.com/forums/p/55085/185853.aspx

Ответ 17

Нет, моно не готов к серьезной работе. Я написал несколько программ в Windows с помощью F # и запустил их в Mono. Эта программа использовала диск, память и процессор довольно интенсивно. Я видел сбои в монобиблиотеках (управляемый код), сбои в собственном коде и сбои в виртуальной машине. Когда моно работали, программы были как минимум в два раза медленнее, чем в .Net в Windows, и использовали гораздо больше памяти. Держитесь подальше от моно для серьезной работы.